题意:n个点,n-1条边及其边的权值(0、1);求每个顶点与它距离最近的点的个数,最后对所有的值进行异或运算。
分析:由题意可知, 求最短距离即求边权为0,。
考虑用并并查集将边权为0 的顶点合并,同时记录每个集合元素的个数。
http://acm.hdu.edu.cn/showproblem.php?pid=5606
#include<cstdio>
#include<iostream>
using namespace std;
#define N 100005
int father[N],Rank[N],num[N];
void init()
{
for(int i=0;i<N;i++){
father[i]=i;
num[i]=1; //初始化,每个集合元素个数为1,每个顶点本身也要算在内
}
}
int find(int x)
{
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
void Union(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return ;
father[y]=x;
num[x]+=num[y];//加权合并
}
int main()
{
int t,n,a,c,b;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
if(!c) //合并边权为0的两个点
Union(a,b);
}
int s=0;
for(int i=1;i<=n;i++)
s^=num[find(i)];
printf("%d\n",s);
}
return 0;
}