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

tree

Accepts: 143

Submissions: 807

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

问题描述

有一个树(nn个点, n-1n−1条边的联通图),点标号从11~nn,树的边权是00或11.求离每个点最近的点个数(包括自己).

输入描述

第一行一个数字TT,表示TT组数据.
对于每组数据,第一行是一个nn,表示点个数,接下来n-1n−1,每行三个整数u,v,wu,v,w,表示一条边连接的两个点和边权.
T = 50,1 \leq n \leq 100000, 1 \leq u,v \leq n,0 \leq w \leq 1T=50,1≤n≤100000,1≤u,v≤n,0≤w≤1.

输出描述

对于每组数据,输出答案.
考虑到输出规模过大,设ans_ians?i??表示第ii个点的答案.你只需输出ans_1 \ xor \ ans_2 \ xor \ ans_3.. \ xor \ ans_nans?1?? xor ans?2?? xor ans?3??.. xor ans?n??即可.

输入样例

1
3
1 2 0
2 3 1

输出样例

1

Hint

ans_1 = 2ans?1??=2
ans_2 = 2ans?2??=2
ans_3 = 1ans?3??=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\n",ans);
64     }
65
66     return 0;
67 }

时间: 2024-07-30 15:27:04

BC68(HD5606) 并查集+求集合元素的相关文章

Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环

D. Dividing Kingdom II Long time ago, there was a great kingdom and it was being ruled by The Great Arya and Pari The Great. These two had some problems about the numbers they like, so they decided to divide the great kingdom between themselves. The

并查集—分离集合森林实现

并查集总结 今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍.20遍.30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解. 并查集,一般使用的是 数组实现.树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找.合并的时间复杂度不会 超过 O(log2n) n个人,m对有亲戚关系的 10 7 1 2 2 3 2 4 3 4 5 6 6 7 8 9 初始化:{1

Codeforces 278C Learning Languages(并查集) 求连通块

Codeforces 278C Learning Languages(并查集) 求连通块 为什么最后还要getfather 一遍 比如 x 是 y 的父亲 然后你 Union(x,z) 然后 z 变成了 x 父亲 然后 y 的祖先就是错的了 题解 求一个无向图中有几个连通块 sum 特判 一下 如果 每一个人的语言都为 0 则答案为 sum 其他 答案则为 sum - 1 1 #include <bits/stdc++.h> 2 using namespace std ; 3 4 const

任意点~并查集求联通块

链接:https://www.nowcoder.com/acm/contest/84/C来源:牛客网 任意点 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可以改变方向. 请问至少需要加多少个点,使得点对之间互相可以到达. 输入描述: 第一行一个整数n表示点数( 1 <= n <= 100).第二行n行,

C. Edgy Trees Codeforces Round #548 (Div. 2) 并查集求连通块

C. Edgy Trees time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a tree (a connected undirected graph without cycles) of nn vertices. Each of the n−1n−1 edges of the tree is col

杭电 1856 More is better (并查集求最大集合)

Description Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements. Mr Wang selected a room big enough to hold the boys. The boy w

并查集(集合合并) + 缩点

正解是dfs的一道题目被我以为成了并查集,结果坑了队友.现在分析一下自己当时为什么会想成是并查集呢. 题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 题意:告诉一张n点m边的图,求哪些边是桥.其实就是缩点,然而却大脑短路,直接认定是并查集了,现在的我真的不能理解当时的自己.... 当时想的是把所有的环缩成一个点,然后剩下的边就是桥了,缩点,第一时间想的就是并查集,其实并查集的操作一般有三个: 1.初始化 把

POJ 3723 Conscription (Kruskal并查集求最小生成树)

Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14661   Accepted: 5102 Description Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to b

并查集:不相交集合

并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.支持三种操作: Make-Set : 用于建立单元素集合. Find-Set:确定元素属于哪一个子集.它可以被用来确定两个元素是否属于同一子集. Union:将两个子集合并成同一个集合. 1.并查集的数组表示 //x表示元素,s[x]表示x所属集合 int s[N]; Make-Set(x){ s[x] = x; } Find-Set(x){ return s[x]; } //将y在所属集合