A Bug's Life——带权并查集
题意:
有N个虫子。科学家认为只有两只虫子不同性别时,才会发生关系。现在给你M个关系,让你判断是否存在同性恋
题解:
d【i】表示 i到根节点的距离 (即同性,异性的关系)
如果x,y在一个集合,并且他们是同性,那么就存在bug
如果 x,y不在一个集合,需要进行集合合并
先让fx指向fy 即 f[fy]=fx;
因为题目给定的 x,y都是异性关系,所以d[x]+d[fx]=d[y]+1
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int maxn = 2e5+7; int f[maxn],d[maxn]; int n,m; int Find(int x) { if(f[x]==x)return x; int root=Find(f[x]); d[x]=(d[x]+d[f[x]])%2; return f[x]=root; } int main() { int t; scanf("%d",&t); int Case=1; while(t--) { scanf("%d%d",&n,&m); for(int i=0; i<=n; i++)f[i]=i,d[i]=0; int flag=1; while(m--) { int x,y; scanf("%d%d",&x,&y); int fx=Find(x); int fy=Find(y); if(fx==fy) { if(d[x]==d[y]) { flag=0; } } else { f[fx]=fy; d[fx]=(d[y]+1-d[x])%2; ///题目给的x,y为异性 所以d[x]+d[fx]=d[y]+1; } } printf("Scenario #%d:\n",Case++); if(flag) { printf("No suspicious bugs found!\n"); } else { printf("Suspicious bugs found!\n"); } printf("\n"); } return 0; }