思路:带权并查集
分析:
1 用rank[i] = 0表示关系相同,用rank[i] = 1表示关系不同
2 在输入的时候把两个元素之间的关系建立起来,然后判断当前的两个元素是否在同一个集合里面,如果是则判断是不是属于同一个类型即可。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<cstdio> using namespace std; const int MAXN = 2010; int father[MAXN]; int rank[MAXN]; void init(int n){ memset(rank , 0 , sizeof(rank)); for(int i = 1 ; i <= n ; i++) father[i] = i; } int find(int x){ if(father[x] != x){ int fa = father[x]; father[x] = find(fa); rank[x] = (rank[x]+rank[fa])%2; } return father[x]; } bool solve(int x , int y){ int fx = find(x); int fy = find(y); if(fx != fy){ father[fx] = fy; rank[fx] = (rank[y]+1-rank[x]+2)%2; return true; } else{ return rank[x] != rank[y]; } } int main(){ int n , m , x , y; int cas = 1 , Case; scanf("%d" , &Case); while(Case--){ scanf("%d%d" , &n , &m); init(n); bool isOk = true; printf("Scenario #%d:\n" , cas++); while(m--){ scanf("%d%d" , &x , &y); if(!solve(x , y)) isOk = false; } if(!isOk) puts("Suspicious bugs found!"); else puts("No suspicious bugs found!"); puts(""); } return 0; }