加入x的子树都已变白,x为黑的画,把x和x的所有儿子反色一下就好了。dfs一遍即可。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=500010;
int n;
bool c[maxn],f[maxn];
struct edge
{
int t;
edge *next;
}*con[maxn];
int read()
{
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x;
}
void ins(int x,int y)
{
edge *p=new edge;
p->t=y;
p->next=con[x];
con[x]=p;
}
void dfs(int v)
{
f[v]=c[v];
for(edge *p=con[v];p;p=p->next)
dfs(p->t),f[p->t]^=f[v];
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
c[i]=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
ins(x,y);
}
dfs(1);
for(int i=1;i<=n;i++)
if(f[i]) printf("%d ",i);
return 0;
}
更巧妙的办法,因为读入的是有父子关系的,我们只要保证父子颜色相同(不同就儿子反一下色),最后保证1为白色即可。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=500010;
int n;
bool c[maxn],f[maxn];
int read()
{
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
c[i]=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
if(c[x]!=c[y]) f[y]=1;
}
f[1]=c[1];
for(int i=1;i<=n;i++)
if(f[i]) printf("%d ",i);
return 0;
}