BC68(HD5606) 并查集+求集合元素

tree

 
 Accepts: 143
 
 Submissions: 807
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
有一个树(nn个点, n-1n1条边的联通图),点标号从11~nn,树的边权是00或11.求离每个点最近的点个数(包括自己).
输入描述
第一行一个数字TT,表示TT组数据.
对于每组数据,第一行是一个nn,表示点个数,接下来n-1n1,每行三个整数u,v,wu,v,w,表示一条边连接的两个点和边权.
T = 50,1 leq n leq 100000, 1 leq u,v leq n,0 leq w leq 1T=50,1n100000,1u,vn,0w1.
输出描述
对于每组数据,输出答案.
考虑到输出规模过大,设ans_iansi​​表示第ii个点的答案.你只需输出ans_1  xor  ans_2  xor  ans_3..  xor  ans_nans1​​ xor ans2​​ xor ans3​​.. xor ansn​​即可.
输入样例
1
3
1 2 0
2 3 1
输出样例
1
Hint
ans_1 = 2ans1​​=2
ans_2 = 2ans2​​=2
ans_3 = 1ans3​​=1
2  xor  2  xor  1=12 xor 2 xor 1=1, 因此输出11.

 马丹!!我想骂人!刚开始做这道题就开始开了一个数组求每一个为0的两个点的数量,最后猛然发现如果三个数都是0答案就不对,然后有想到了深搜,用vector,存与之相连为0的点,写到一半,发现又不对!马丹,猛然想起就是并查集啊,把为0的点放在一起,就是就每个集合中数的个数嘛!敲了不到10分钟敲完,卡在8:45提交了,WA了,擦!猛然发现一个细节给忽略了,果断改了,8:46了。。。呵呵呵呵。。刚才提交a了,擦!太弱了,伤心的是又掉rating了....

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <vector>
 6 using namespace std;
 7 const int MAX = 100000 + 10;
 8 int num[MAX],father[MAX];
 9 int find_father(int x)
10 {
11     int r = x;
12     while(r != father[r])
13         r = father[r];
14     int i = x,j;
15     while(r != father[i])
16     {
17         j = father[i];
18         father[i] = r;
19         //num[r] += num[father[i]] 擦!就是这!没必要啊,以为此时num[r]中肯定含有num[father[i]],因为这只是跟新直系跟节点,数量并不需修改!!!
20         i = j;
21     }
22     return r;
23 }
24 void Union(int x, int y)
25 {
26     int fx = find_father(x);
27     int fy = find_father(y);
28     if(fx != fy)
29     {
30         father[fx] = fy;
31         num[fy] += num[fx];
32     }
33 }
34 int main()
35 {
36     int t;
37     scanf("%d", &t);
38     while(t--)
39     {
40         int u,v,w,n;
41         scanf("%d", &n);
42         for(int i = 1; i <= n; i++)
43         {
44             father[i] = i;
45             num[i] = 1;
46         }
47         for(int i = 1; i < n; i++)
48         {
49             scanf("%d%d%d", &u,&v,&w);
50             if(w == 0)
51             {
52                 Union(u,v);
53             }
54         }
55         int temp = find_father(1);
56         int ans = num[temp];
57 
58         for(int i = 2; i <= n; i++)
59         {
60             int fx = find_father(i);
61             ans = ans ^ num[fx];
62         }
63         printf("%d
",ans);
64     }
65 
66     return 0;
67 }
View Code
原文地址:https://www.cnblogs.com/zhaopAC/p/5095325.html