这个题面真是。。污浊不堪啊(/▽\)
和上一个题几乎一眼的思路
记一个我的WA点吧
合并的时候如果是分属两个不同的集合的话,那么不能直接的把合并过去的根节点的权值置为1,而是要根据两个子节点的关系来判断,其它的好像没什么
(注意每一组输入之间要有空行。。这也是十分的蛋疼的233333
--------------------我还是代码的混割线--------------------------------------
#include<cstdio>
#include<cstring>
using namespace std;
const int maxm=1123456;
const int maxn=21234;
int l[maxm],r[maxm];
int arr[maxn],val[maxn]; // val = 0 same as root / val = 1 differ ans root
void init(int n){
for(int i=0;i<=n;i++){
arr[i]=i,val[i]=0;
}
}
int fnd(int x){
if(x==arr[x])
return x;
else{
int root = fnd(arr[x]); // 00 0 11 0 01 1 10 1
val[x] =(val[x] != val[arr[x]]);
return arr[x] = root;
}
}
bool join(int x,int y){
int rx = fnd(x);
int ry = fnd(y);
if(rx!=ry){
arr[rx]=ry;
val[rx]= (val[x] == val[y]);
return true;
}
else{
return val[x]!=val[y];
}
}
void out(int *s,int n){
for(int i=1;i<=n;i++)
printf(i<n?"%d ":"%d\n",s[i]);
}
bool check(int n,int m){
init(n);
for(int i=0;i<m;i++){
// out(arr,n);
// out(val,n);
// puts("----------------------");
if(join(l[i],r[i])==false){
return false;
}
}
return true;
}
int main(){
int T;
int n,m;
scanf("%d",&T);
int icase = 1;
while(T-- && ~scanf("%d %d",&n,&m)){
if(icase!=1) puts("");
for(int i=0;i<m;i++){
scanf("%d %d",&l[i],&r[i]);
}
printf("Scenario #%d:\n",icase++);
if(check(n,m)){
puts("No suspicious bugs found!");
}
else{
puts("Suspicious bugs found!");
}
}
return 0;
}