tree
There is a tree(the tree is a connected graph which contains nn points and n-1n−1 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.
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]T≤50,n≤105,u,v∈[1,n],w∈[0,1]
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.
1 3 1 2 0 2 3 1
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; }