tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 277 Accepted Submission(s): 147
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.
题意:有n个点,n-1条边构成连通图。每条边的权值为0或者1,求离每个点最近的点的个数(包括自己),n个数字相异或。
题解:因为n个点n-1条边构成的连通图一定是线性的。每个点离自己最近的一定是自己和权值为0的边相连的点。可以用并查集统计最近点个数,把权值为0的边的两点连在一棵树上,树的节点的个数就是这些点的最近点个数。左右边权都是1的点,最近点就是自己,个数为1。
代码如下:
#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int tree[maxn];
int father[maxn],n;
int find(int x)
{
if(tree[x]==x)
return x;
else
return tree[x]=find(tree[x]);
}
void megre(int a,int b)
{
int fa,fb;
fa=find(a);
fb=find(b);
if(fa!=fb)
{
tree[fa]=fb;
father[fb]+=father[fa];
//if(father[fb]>cnt)
//cnt=father[fb];
}
}
int main()
{
int t,n,i,u,v,w,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int m=n-1;
for(i=1;i<=n;++i)
{
tree[i]=i;
father[i]=1;
}
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
if(w==0)
megre(u,v);
}
int ans=father[find(1)];//注意查找的是根节点,不是父节点
for(i=2;i<=n;++i)
ans^=father[find(i)];
printf("%d\n",ans);
}
return 0;
}