题目链接:点击打开链接
题意:昆虫有两种性别:雌性和雄性,给出m对昆虫的编号,表示每对昆虫是异性关系,问是否存在矛盾,即可能有一对是同性关系
分析:可以将同性关系的昆虫合并入并查集,当某对昆虫的根结点相等(即是同性关系)时,这时存在矛盾, 如果所有对昆虫的根结点都不相同(即表示所有对昆虫都是异性关系),这时不存在矛盾。因为输入的每一对昆虫事先被确定为异性关系,所以可以用数组sex[i]表示和i异性的昆虫,那么,对于一对昆虫a和b,和a同性的是sex[b],和b同性的是sex[a],于是每次merge(sex[a],b)和merge(sex[b],a)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=2005;
int pre[maxn]; //存储同性的信息,pre[i]表示i的父结点
int sex[maxn];//存储异性的信息,sex[i]表示i的异性
int n,m;
void init()
{
for(int i=1;i<=n;i++)
pre[i]=i;
}
int root(int x)
{
return pre[x]==x?x:pre[x]=root(pre[x]);
}
void merge(int x,int y) //合并x和y
{
if(root(x)!=root(y)) //去重条件,如果x和y都在并查集中就不用再次合并了
{
pre[root(x)]=root(y);
}
}
int main()
{
int T;
cin>>T;
int cnt=1;
while(T--)
{
scanf("%d%d",&n,&m);
init();
memset(sex,0,sizeof sex);
int a,b;
bool flag=false;
while(m--)
{
scanf("%d%d",&a,&b);
if(root(a)==root(b)) { flag=true; continue; }
if(sex[a]==0) //如果a之前没有发现和它异性的,就将a的异性置为b
sex[a]=b;
else merge(sex[a],b);//如果之前有与存在异性关系的昆虫sex[a],就将sex[a]和b合并
if(sex[b]==0)
sex[b]=a;
else merge(sex[b],a);
}
printf("Scenario #%d:\n",cnt++);
if(flag)
puts("Suspicious bugs found!");
else puts("No suspicious bugs found!");
puts("");
}
return 0;
}