hdu 5905tree

tree
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other)
Total Submission(s) : 8 Accepted Submission(s) : 6
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.

ans1=2

ans2=2

ans3=1

2 xor 2 xor 1=1,so you need to output 1.

给你n个点的联通,让你找出与每个点的最短连接点,连接点包括它自己,然后将每个点的最短连接点个数进行或非运算
注意如果有多个点之间w都为0,我们均要将其作为一个集合,因此
直接对每个点进行处理,不过我们在rank值时变为1,然后只要当w=0时就进行并查,最后统计所有集合的点然后或非操作

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define N 100010
using namespace std;
int map[N];
int rank_[N];
int n;
void init(int n)
{
    int i;
    for(i=1; i<=n; i++)
        map[i]=i,rank_[i]=1;
}
int find(int x)
{
    if(x!=map[x])
        map[x]=find(map[x]);
    return map[x];
}
void Union(int x,int y)
{
    x=find(x),y=find(y);
    if(x!=y)
    {
        map[x]=y;
        rank_[y]+=rank_[x];
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        init(n);
        int u,v,w;
        int sum=0;
        for(int i=1; i<=n-1; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            if(w==0)
                Union(u,v);
        }
        for(int i=1; i<=n; i++)
        {
            if(map[i]==i&&rank_[i]%2==1)
                sum=rank_[i]^sum;
        }
        cout<<sum<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值