hdu 5606 tree(并查集)

来源:互联网 发布:js array concat 编辑:程序博客网 时间:2024/04/27 23:03

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5606

tree

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


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)


题目大意:

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


解题思路:一开始想着只要判断w为0就好了,w为0的时候直接给连通的这两个点都加1处理,最后再加上本身这个点就是答案了!!但是这个是错误的!!!wrong answer!!!
下面解释一下:举一个例子:
    1
 4
 1 2 0
 2 3 0
 1 4 0如果是这组数据的话,我们需要怎么处理呢?如果按照上述说法计算的话,对于1这个点,与其最近的点只有两个,但实际上有三个!!所以就不可以采用上述方法,所以采用并查集的方法,只要w=0就给连通起来。在计算个数即可。

详见代码。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int num[100010];int fa[100010];int Find(int x){    if (x!=fa[x])    {        return fa[x]=Find(fa[x]);    }    return x;}void Unit(int x,int y){    x=Find(x);    y=Find(y);    if (x!=y)    {        fa[x]=y;        num[y]+=num[x];//把两个点连通,同时也要加上子节点在这之前就已经连通的点    }}int main(){    int t;    scanf("%d",&t);    while (t--)    {        int n;        scanf("%d",&n);        for (int i=1; i<=n; i++)            fa[i]=i,num[i]=1;        int u,v,w;        int s=0;        for (int i=1; i<=n-1; i++)        {            scanf("%d%d%d",&u,&v,&w);            if (w==0)            {                Unit(u,v);            }        }        for (int i=1; i<=n; i++)        {            if (fa[i]==i&&num[i]%2==1)                s=num[i]^s;        }        printf ("%d\n",s);    }    return 0;}



0 0