Codeforces 429(#245 Div1) A. Xor-tree

問題

n頂点からなる根付き木が与えられる。各頂点は最初0または1である。
このグラフに対して次の操作が好きなだけできる。


操作:好きな頂点vをえらび、vおよび、vの子孫uでdepth(u)-depth(v)が偶数の頂点uの0, 1を反転させる。


最終状態が与えられるとき、その状態にするための操作の回数の最小値を求めよ。

制約条件

n≦10^5

方針

同じ頂点で2度操作をしないとすれば、操作の仕方は一意に定まる。
(根から順に見ていって、最終状態と違うなら反転する)
ので、単にDFSすればいい。

ソースコード

const int MX = 100010;
int n, a[MX], b[MX];
vector<vi> e;

vi ans;

int rec(int c, int p, int flip, int depth){
	
	rep(f, 2){
		if((flip >> depth & 1 ^ f) != (a[c] ^ b[c])) continue;
		int tmp = f;
		if(f) ans.pb(c + 1);
		
		rep(i, e[c].size()) if(e[c][i] != p)
			tmp += rec(e[c][i], c, flip ^ (f << depth), depth ^ 1);
		return tmp;
	}
}

int main(){
	cin >> n;
	e.resize(n);
	rep(i, n - 1){
		int a, b; cin >> a >> b;
		a--; b--;
		e[a].pb(b);
		e[b].pb(a);
	}
	rep(i, n) cin >> a[i];
	rep(i, n) cin >> b[i];
	
	cout << rec(0, 0, 0, 0) << endl;
	rep(i, ans.size()) cout << ans[i] << endl;
	
	return 0;
}