思路:带权并查集
分析:
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;
}