hdu--5606(简单并查集)

tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 586    Accepted Submission(s): 286


Problem Description
There is a tree(the tree is a connected graph which contains  n  points and  n1  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.

T50,n105,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.
 
解题思路:这道题可谓是WA啊,WA啊.第一次写,当输入时边的权值为0,则该边两个端点记录num[ ]自增一次(记录与之距离为0的)
的点的总数),但忽略了传递性,例如a--b=0;b--c=0;那么a--b=0;然而我并没有合并。第二次写,用的是并查集,把距离为0
的点绑在一棵树上,该树上的结点数就等于该树上距每个点距离最近的点的数目,然而忘了可能最后会构成多种情况,例如,四个点,边2--4=0,1--2=1,1--3=0,这里2,4在一棵树上,1--3在一棵树上,而不是按我写的2,4,1,3在同一棵树上。再改了改,终于AC了。

代码如下:
#include<stdio.h>
int per[100000+10];
int power[100000+10];
void inin(int n){
	for(int i=1;i<=n;i++){
		per[i]=i;
		power[i]=1;
	}
}
int find(int x){
	return per[x]=x==per[x]?x:find(per[x]);
}
void judge(int x,int y){
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy){
		per[fx]=fy;
		power[fy]+=power[fx];
	}
}
int main(){
	int t,n,a,b,c;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		inin(n);
		for(int i=1;i<n;i++){
			scanf("%d%d%d",&a,&b,&c);
			if(c==0){
				judge(a,b);
			}
		}
		int ans=power[find(1)];
		for(int i=2;i<=n;i++){
			ans^=power[find(i)];
		}
		printf("%d\n",ans);
	}
	return 0;
}


你可能感兴趣的:(hdu--5606(简单并查集))