HDU5606 tree 并查集+思维

来源:互联网 发布:厦门市中医院网络预约 编辑:程序博客网 时间:2024/05/17 05:01

1.题目描述:

tree

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


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
131 2 02 3 1
 

Sample Output
1in the sample.$ans_1=2$$ans_2=2$$ans_3=1$$2~xor~2~xor~1=1$,so you need to output 1.
 

Source
BestCoder Round #68 (div.2)
 

Recommend
hujie   |   We have carefully selected several similar problems for you:  6018 6017 6016 6015 6014 
2.题意概述:

一棵树,权值只有0和1,找到每个点与之相距最近的点的个数, (包括这个点自己,也就是说,等价于找每个点与之相距为0的点的个数)。

3.解题思路:

连通块问题可以考虑用并查集维护,每次输入的两个数权值为0则合并,权值非0则不合并,连通同时用一个size维护树的大小,最后统计一下输出就行。

4.AC代码:

#include <stdio.h>#define maxn 101000using namespace std;int pa[maxn], ans[maxn], size[maxn];void init(int n){for (int i = 1; i <= n; i++){pa[i] = i;ans[i] = 0;size[i] = 1;}}int findset(int x){if (pa[x] == x)return x;return pa[x] = findset(pa[x]);}void unionset(int a, int b){int a1 = findset(a);int b1 = findset(b);if (a1 != b1){if (size[a1] < size[b1]){pa[a1] = b1;size[b1] += size[a1];}else{pa[b1] = a1;size[a1] += size[b1];}}}int main(){int t, n;scanf("%d", &t);while (t--){scanf("%d", &n);init(n);for (int i = 0; i < n - 1; i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);if (!w)unionset(u, v);}for (int i = 1; i <= n; i++){ans[i] = size[findset(i)];if (i > 1)ans[i] ^= ans[i - 1];}printf("%d\n", ans[n]);}    return 0;}

0 0
原创粉丝点击