A Bug's Life
题意
题意很简单,就是给M组虫虫谁喜欢谁的关系,然后判断一下有没有同性恋的虫虫。
坑点:每一组数据输出之后还需要输出一个空行
分析
此题我以前用过二分图来做,这里用带权并查集做。如果存在这么一串关系,x->y->z(x喜欢y,y喜欢z),
然后存储x,y,z
到根结点的距离,dis[x] = 0,dis[y] = 1,dis[z] = 2
,如果此刻又来了一个喜欢关系x->z
,我们发现dis[x]%2 == dis[z]%2,所以x
,z他们是同性关系,所以发现了同性恋虫虫
一句话:如果两个到根结点的距离是奇偶性相同的结点相爱,那么他两必定有一位是同性恋
AC代码
#include <iostream> #include <algorithm> #include <stdio.h> using namespace std; const int maxn = 1e6+10; int T,N,M; int fa[maxn],dis[maxn]; void init(){ for(int i = 1;i<=N;i++) { fa[i] = i; dis[i] = 0; } } int find(int x){ if(x != fa[x]){ int f = fa[x]; fa[x] = find(fa[x]); dis[x] += dis[f]; } return fa[x]; } void join(int x,int y){ int fx = find(x),fy = find(y); if(fx != fy){ fa[fx] = fy; dis[fx] = 1+dis[y]-dis[x]; } } int main(){ cin>>T; int kase = 1; while(T--){ printf("Scenario #%d:\n",kase++); bool have = false; cin>>N>>M; init(); while(M--){ int x,y; scanf("%d%d",&x,&y); if(find(x) != find(y)){ join(x,y); }else{ if(dis[x]%2 == dis[y] %2){ have = true; } } } if(have) puts("Suspicious bugs found!"); else puts("No suspicious bugs found!"); puts(""); } return 0; }
ps:对同性恋无偏见,只是便于描述问题