tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 452 Accepted Submission(s): 225
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≤10
5
,u,v∈[1,n],w∈[0,1]
for each test case,the first line is a nubmer n
T≤50,n≤10
Output
for each test case,you need to print the answer to each point.
in consideration of the large output,imagine ans
i![]()
is the answer to point
i
,you only need to output,
ans
1
xor ans
2
xor ans
3
.. ans
n![]()
.
in consideration of the large output,imagine ans
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<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int pre[maxn],mark[maxn];
int find(int x)
{
return x==pre[x]?x:pre[x]=find(pre[x]);
}
void join(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
pre[fa]=fb;
}
int main()
{
int t,n,a,b,v;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
pre[i]=i;
for(int i=1;i<n;++i)
{
scanf("%d%d%d",&a,&b,&v);
if(!v)
join(a,b);
}
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;++i)
mark[find(i)]++;
int sum=0;
for(int i=1;i<=n;++i)
{
if(mark[i])
{
int tem=mark[i];
while(tem--)
sum=sum^mark[i];
}
}
printf("%d\n",sum);
}
return 0;
}