大意:一个叫兽要研究一种虫子是否用同性恋的现象,给你几对恋爱的虫子
默认只有两种性别(???),问你是否存在同性恋的现象
----------------------------------------------------------------------------------------------(分割线)
如果忽视题意的话
是一道经典的带权并查集好题
考虑虫子只有两个种类
我们在合并并查集的时候再维护一个关系数组,表示这个点和根节点的关系(异性/同性)
这样我们可以知道同一个并查集内任意两点之间的关系
合并的时候两个并查集取反一下就是了
而如果出现两个相同的,就说明不满足条件
而关系只有0/1两种,用异或可以很方便的进行计算
话说输出记得打两个换行,我也不知道为什么要卡这个
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
int T,n,m,fa[2005],rel[2005];
inline int find(int x){
int pre=fa[x];
if(fa[x]!=x){
fa[x]=find(fa[x]);
rel[x]=(rel[x]^rel[pre]);
}
return fa[x];
}
int main(){
T=read();
for(int cas=1;cas<=T;cas++){
memset(fa,0,sizeof(fa));memset(rel,0,sizeof(rel));
n=read(),m=read();bool flag=false;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
int u=read(),v=read();
int f1=find(u),f2=find(v);
if(f1!=f2){
fa[f1]=f2;rel[f1]=(rel[u]^rel[v]^1)%2;
}
else{
if((rel[u]^rel[v])==0){
flag=true;
}
}
}
printf("Scenario #%d:
",cas);
if(flag)printf("Suspicious bugs found!
");
else printf("No suspicious bugs found!
");
}
}