Codeforces 429 A. Xor-tree
2016-03-12 18:27
429 查看
题目意思:
给一颗n个节点的树,每个节点有一个值要么是0要么是1,改变某个节点的值时,它的儿子不变,它儿子的儿子翻转,它儿子的儿子的儿子不变,如此类推。给定各个节点的目标值,求最少的翻转次数,使得达到要求。
题解思路:
先建树,然后从根节点开始dfs,维护一个从根传过来的奇数层改变的次数,从根传过来的偶数层改变的次数,根据当前节点所在层的奇偶性以及原始值和目标值的差异,判断该节点是否需要改变,如果要改变就一定改变,然后更新传给叶子的参数。
父亲一定要改,儿子不一定改。
给一颗n个节点的树,每个节点有一个值要么是0要么是1,改变某个节点的值时,它的儿子不变,它儿子的儿子翻转,它儿子的儿子的儿子不变,如此类推。给定各个节点的目标值,求最少的翻转次数,使得达到要求。
题解思路:
先建树,然后从根节点开始dfs,维护一个从根传过来的奇数层改变的次数,从根传过来的偶数层改变的次数,根据当前节点所在层的奇偶性以及原始值和目标值的差异,判断该节点是否需要改变,如果要改变就一定改变,然后更新传给叶子的参数。
父亲一定要改,儿子不一定改。
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <list> #include <queue> #include <map> using namespace std; vector<int> edge[100010],ans; int n,a[100010],b[100010]; int vis[100010]; void dfs(int x,int now,int odd,int even) { if(vis[x]) return; vis[x]++; if((now && odd) || !now && even) a[x] ^= 1; if(a[x] != b[x]) { ans.push_back(x); if(now) odd ^= 1; else even ^= 1; } for(int i = 0; i < edge[x].size(); i++) { int y = edge[x][i]; dfs(y,(now+1)%2,odd,even); } } int main() { int t,C = 1; //scanf("%d",&t); while(scanf("%d",&n) != EOF) { memset(edge,0,sizeof(edge)); memset(vis,0,sizeof(vis)); for(int i = 0; i < n-1; i++) { int u,v; scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } for(int i = 1; i <= n; i++) scanf("%d",&a[i]); for(int i = 1; i <= n; i++) scanf("%d",&b[i]); dfs(1,1,0,0); printf("%d\n",ans.size()); for(int i = 0; i < ans.size(); i++) printf("%d\n",ans[i]); } }
相关文章推荐
- 直线拟合算法
- 复利计算器2.0
- 构建之法阅读笔记01
- 优化
- Spring使用p空间配置属性——基于XML Schema的简化配置
- Codeforces Round #307 (Div. 2) 551D - GukiZ and Binary Operations 矩阵快速幂
- Wilbur and Swimming Pool(矩形求面积)
- C++第一次实验—3
- python爬虫:爬取慕课网视频
- Android实践 -- 登录+找回密码+注册
- 4- java client api
- bzoj 2083 (二分查找)
- 对360软件的评价
- Android 线程与线程池 Thread&ThreadPool
- 利用GDB跟踪分析linux内核启动
- Ubuntu下开发常用操作技巧.
- 一百以内四则运算
- 0312 复利计算
- 学习进度01
- Sicily 1148 过河