http://codeforces.com/problemset/problem/430/C
题意:在一棵上有n个节点,有n-1条边,在每一个节点上有一个值0或1,然后给你一个目标树,让你选择节点,然后把节点的值翻转,它的孙子节点跟着翻转,依次类推。。。问经过最少次数可以使这棵树变成目标树。
思路:利用异或的性质,任何数和0异或为它本身,从根节点dfs就行。
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 #define maxn 200100 6 using namespace std; 7 8 int n,k,x; 9 int a[maxn]; 10 int b[maxn]; 11 int num[maxn]; 12 bool vis[maxn]; 13 vector<int>g[maxn]; 14 int ans[maxn]; 15 int cnt; 16 void dfs(int c,int x,int y) 17 { 18 if((a[c]^x)!=b[c]) 19 { 20 ans[cnt++]=c; 21 x=!x; 22 } 23 for(int i=0; i<(int)g[c].size(); i++) 24 { 25 int v=g[c][i]; 26 if(!vis[v]) 27 { 28 vis[v]=true; 29 dfs(v,y,x); 30 } 31 } 32 } 33 34 int main() 35 { 36 scanf("%d",&n); 37 for(int i=1; i<n; i++) 38 { 39 int u,v; 40 scanf("%d%d",&u,&v); 41 g[u].push_back(v); 42 g[v].push_back(u); 43 } 44 for(int i=1; i<=n; i++) 45 { 46 scanf("%d",&a[i]); 47 } 48 for(int i=1; i<=n; i++) 49 { 50 scanf("%d",&b[i]); 51 } 52 vis[1]=true; 53 dfs(1,0,0); 54 printf("%d\n",cnt); 55 for(int i=0; i<cnt; i++) 56 { 57 printf("%d\n",ans[i]); 58 } 59 return 0; 60 }