问题:边为0的节点可以联合起来,都算是最亲近的点,例如1到2距离为0,2到3距离为0,则3也是1最亲近的点
距离为1的两点不属于同一棵树(并查集角度的树)。
注意点:边的权重取值为0或者1,而不是从0到1
#if 1
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=100005;
int parent[MAXN];
int cnt[MAXN];//记录每棵树的节点数
bool flag[MAXN];//记录节点个数为奇数或是偶数
bool flagIsRoot[MAXN];//记录每个节点是否为根节点
int find_set(int x)
{
return parent[x]!=x?parent[x]=find_set(parent[x]):x;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
int n;
scanf("%d",&n);
//init parent array
for(int j=1;j<=n;j++)
{
parent[j]=j;
cnt[j]=1;//contains itself
flag[j]=true;//代表奇数1
flagIsRoot[j]=true;
}
for(int j=1;j<n;j++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(w==0)
{
int pu,pv;
pu=find_set(u);
pv=find_set(v);
parent[pu]=pv;
cnt[pv]+=cnt[pu];
//需要根据加进来的pu的节点数来统计好pv树最终节点的奇偶个数
if(flag[pv])
{
flag[pv]=!flag[pu];
}
else
{
flag[pv]=flag[pu];
}
flagIsRoot[pu]=false;
}
}
int result=0;
for(int j=1;j<=n;j++)
if(flagIsRoot[j]&&flag[j])
{
result=result^cnt[j];
}
printf("%d\n",result);
}
return 0;
}
#endif // 1