#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX_N 5000
#define MAX_K 1000005
using namespace std;
//完成n个元素的初始化
int x[MAX_K];
int y[MAX_K];
int n,k;
int par[MAX_N];
int rank[MAX_N];
void init(int n)
{
for(int i=0;i<n;i++)
{
par[i]=i;
rank[i]=0;
}
}
//查询树的根
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);//路径压缩,对于每个节点,一旦向上走到了一次根节点,就把这个店到父亲的边改为直接连向边
}
//合并x和y所属的集合
void unite(int x,int y)
{
//找到x和y的根,并判断根是否相同
x=find(x);
y=find(y);
if(x==y)
return ;
if(rank[x]<rank[y])
{
//将x设为y的子树
par[x]=y;
}
else{
par[y]=x;
if(rank[x]==rank[y])
rank[x]++;
}
}
bool same(int x,int y)
{
//只需要判断他们的根节点是否相同即可
return (find(x)==find(y));
}
int t,g;
int main()
{
scanf("%d",&t);
g=t;
while(t--)
{
scanf("%d %d",&n,&k);
for(int i=0;i<k;i++)
{
scanf("%d %d",x+i,y+i);
}
void solve();
solve();
}
}
void solve()
{
int ans=0;
init(n*2);
for(int i=0;i<k;i++)
{
int a=x[i]-1;
int b=y[i]-1;
if(a<0||b<0||a>=n||b>=n)
{
printf("Scenario #%d:\nSuspicious bugs found!\n\n",g-t);
return ;
}
if(same(a,b))
{
printf("Scenario #%d:\nSuspicious bugs found!\n\n",g-t);
return ;
}
else{
unite(a,b+n);
unite(a+n,b);
}
}
printf("Scenario #%d:\nNo suspicious bugs found!\n\n",g-t);
}
抛开题意有多open不说,我们需要完成的就是对昆虫分类,分为男和女,由于n的范围是小于等于2000,我们可以对比食物链的那道题,将par[5];
分为两类:a,b是同一性别
A+n和b,b+n和a是异性