Codeforces 429 A. Xor-tree

Description
Iahub is very proud of his recent discovery, propagating trees. Right now, he invented a new tree, called xor-tree. After this new revolutionary discovery, he invented a game for kids which uses xor-trees.

The game is played on a tree having n nodes, numbered from 1 to n. Each node i has an initial value initi, which is either 0 or 1. The root of the tree is node 1.

One can perform several (possibly, zero) operations on the tree during the game. The only available type of operation is to pick a node x. Right after someone has picked node x, the value of node x flips, the values of sons of x remain the same, the values of sons of sons of x flips, the values of sons of sons of sons of x remain the same and so on.

The goal of the game is to get each node i to have value goali, which can also be only 0 or 1. You need to reach the goal of the game by using minimum number of operations.

Input
The first line contains an integer n (1 ≤ n ≤ 105). Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ n; ui ≠ vi) meaning there is an edge between nodes ui and vi.

The next line contains n integer numbers, the i-th of them corresponds to initi (initi is either 0 or 1). The following line also contains n integer numbers, the i-th number corresponds to goali (goali is either 0 or 1).

Output
In the first line output an integer number cnt, representing the minimal number of operations you perform. Each of the next cnt lines should contain an integer xi, representing that you pick a node xi.

Sample Input
Input
10
2 1
3 1
4 2
5 1
6 2
7 5
8 6
9 8
10 5
1 0 1 1 0 1 0 1 0 1
1 0 1 0 0 1 1 1 0 1
Output
2
4
7

思路:
对于每一个节点如果当前节点根据前面一层传来的数据需要修改其值那么就修改。由于值是在0,1之间转换,所以对同一节点偶数次的修改就相当于未修改,奇数次的修改相当于只修改一次,所以需要记录此层需要修改的次数,等到访问到此层的时候再修改,这样可以减少时间。

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int n,a[100009],b[100009];
vector<int> mp[100009],ans;
int vis[100009];
void dfs(int x,int now,int odd,int even)
//x为当前节点的标号,now为当前节点所在层数的奇偶性,
//odd保存当前奇数层节点需要修改的次数,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<mp[x].size();i++)
        dfs(mp[x][i],(now+1)%2,odd,even);
}
int main()
{
    scanf("%d",&n);
    int u,v;
    for(int i=0;i<n-1;i++)
    {
        scanf("%d%d",&u,&v);
        mp[u].push_back(v);
        mp[v].push_back(u);
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int j=1;j<=n;j++)
        scanf("%d",&b[j]);
    dfs(1,1,0,0);
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++)
        printf("%d\n",ans[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值