• tree(简单并差集)


    tree

     
     Accepts: 156
     
     Submissions: 807
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    Problem Description

    There is a tree(the tree is a connected graph which contains nn points and n-1n1 edges),the points are labeled from 1 to nn,which edge has a weight from 0 to 1,for every point iin[1,n]i[1,n],you should find the number of the points which are closest to it,the clostest points can contain ii itself.

    Input

    the first line contains a number T,means T test cases.

    for each test case,the first line is a nubmer nn,means the number of the points,next n-1 lines,each line contains three numbers u,v,wu,v,w,which shows an edge and its weight.

    Tle 50,nle 10^5,u,vin[1,n],win[0,1]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 ans_iansi​​ is the answer to point ii,you only need to output,ans_1~xor~ans_2~xor~ans_3..~ans_nans1​​ xor ans2​​ xor ans3​​.. ansn​​.

    Sample Input
    1
    3
    1 2 0
    2 3 1
    Sample Output
    1
    
    in the sample.
    
    ans_1=2ans1​​=2
    
    ans_2=2ans2​​=2
    
    ans_3=1ans3​​=1
    
    2~xor~2~xor~1=12 xor 2 xor 1=1,so you need to output 1.
    题解:找每个点距离自己最近的点的个数的异或值,注意最近点包括自己;
    思路:并差集,将权值为0的点组成一颗树,这棵树代表的就是距离自己最近的点的个数;
    代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<set>
    using namespace std;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define  PI(x) printf("%d",x)
    #define P_ printf(" ")
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    const int MAXN=100010;
    int a[MAXN];
    int n;
    struct Node{
    	int u,v,w;
    	Node init(){SI(u);SI(v);SI(w);}
    }dt[MAXN];
    int pre[MAXN],num[MAXN];
    int find(int x){
    	return pre[x]=x==pre[x]?x:find(pre[x]);
    }
    void merge(Node a){
    	int f1=find(a.u),f2=find(a.v);
    	if(pre[f1]!=f2)pre[f2]=f1,num[f1]+=num[f2];
    }
    void initial(){
    	for(int i=1;i<=n;i++)pre[i]=i,num[i]=1;
    }
    int main(){
    	int T;
    	SI(T);
    	while(T--){
    		mem(a,0);
    		SI(n);
    		initial();
    		int u,v,w;
    		for(int i=0;i<n-1;i++){
    			dt[i].init();
    			w=dt[i].w;
    			if(!w)merge(dt[i]);
    		}int ans=0;
    		for(int i=1;i<=n;i++)ans^=num[pre[i]];
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    java集合Collection常用方法详解
    JavaWeb_cookie和session
    JavaWeb_Cookie
    Java中双向链表
    Java链表基础
    select函数详解及实例分析
    socket select函数的详细讲解
    记录远程用户登录日志
    MSSQL grant
    dll 中使用ADO
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5095276.html
Copyright © 2020-2023  润新知