http://acm.hdu.edu.cn/showproblem.php?pid=5606
//将权值为0的点uni()起来,形成并查集
Problem Description
There is a tree(the tree is a connected graph which contains n points and n−1 edges),the points are labeled from 1 to n ,which edge has a weight from 0 to 1,for every point i∈[1,n] ,you should find the number of the points which are closest to it,the clostest points can contain i itself.
Input
the first line contains a number T,means T test cases.
for each test case,the first line is a nubmer n ,means the number of the points,next n-1 lines,each line contains three numbers u,v,w ,which shows an edge and its weight.
T≤50,n≤105,u,v∈[1,n],w∈[0,1]
Output
for each test case,you need to print the answer to each point.
in consideration of the large output,imagine ansi is the answer to point i ,you only need to output,ans1 xor ans2 xor ans3.. ansn
Sample Input
1 3 1 2 0 2 3 1
Sample Output
1 in the sample. $ans_1=2$ $ans_2=2$ $ans_3=1$ $2~xor~2~xor~1=1$,so you need to output 1.
//求解距离自己最近点有多少个、注意是最近当然包括自身、当然只包括权值为0的节点
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=100010;
ll fa[maxn];
ll nums[maxn];
ll rela[maxn];
bool bugs;
void init(ll n)
{
for(ll i=1; i<=n; i++)
fa[i]=i,rela[i]=0;
}
ll find(ll x)
{
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
void uni(ll a,ll b)
{
ll aa=find(a);
ll bb=find(b);
if(aa!=bb)
fa[aa]=bb;
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--)
{
memset(nums,0,sizeof(nums));
ll n;
cin>>n;
init(n);
ll m=n-1;
ll u,v,w;
for(ll i=0; i<m; i++)
{
scanf("%lld %lld %lld",&u,&v,&w);
if(w==0)uni(u,v);
}
for(ll i=1; i<=n; i++)
{
nums[find(i)]++;//每一个节点归结于同一根节点;
}
ll ans=nums[find(1)];//异或所有的点的值;
for(ll i=2; i<=n; i++)
{
ans ^=nums[find(i)];
}
cout<<ans<<endl;
}
return 0;
}