给定一棵树,树的每个结点上有一个值,你可以对树上的值进行异或操作,求使树上的结点值成为目标值所需的最少操作
我们可以发现,如果第一次是对奇数层进行操作,那么第二次再对偶数层进行操作时,上一步的操作就会作废。发现这个性质后,就可以dfs求解。如果需要翻转奇数层,则之前偶数层的操作将作废;如果需要反转偶数层,则之前奇数层的操作将作废。这样的话只需要dfs一次就可以求出解
#include<bits/stdc++.h>
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<long,long> PLL;
typedef pair<char,char> PCC;
typedef long long LL;
const int N=3*1e5+10;
const int M=150;
const int INF=0x3f3f3f3f;
const int MOD=998244353;
int n,init[N],goal[N];
vector<int> g[N];
vector<int> ans;
void dfs(int node,int father,int state,int odd,int even){
if((state && odd) || (!state && even)) init[node]^=1;
if(init[node]!=goal[node]){
ans.push_back(node);
if(state) odd^=1;
else even^=1;
}
for(int i=0;i<g[node].size();i++){
if(g[node][i]==father) continue;
dfs(g[node][i],node,(state+1)%2,odd,even);
}
}
void solve(){
cin>>n;
for(int i=0;i<n-1;i++){
int x,y;cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
for(int i=1;i<=n;i++) cin>>init[i];
for(int i=1;i<=n;i++) cin>>goal[i];
dfs(1,-1,1,0,0);
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++) cout<<ans[i]<<endl;
}
int main(){
IOS;
solve();
return 0;
}