这道题的思路不是自己想的,参考了别人的代码。数组par为并查集数组,pre为辅助数组。pre[i]为i个体之前对应的异性,与当前的异性属于同性,因此合并。然后就是查看是否同一个根节点啦~
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int par[3000], pre[3000];
int n, m;
void init()
{
for(int i = 1; i <= n; i++) par[i] = i;
}
int find1(int x)
{
int r = x, j;
while(r != par[r]) r = par[r];
while(x != r) j = par[x], par[x] = r, x = j;
return r;
}
void unite(int x, int y)
{
x = find1(x);
y = find1(y);
par[x] = y;
}
int main()
{
int t, a, b, x = 0;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
init();
memset(pre, 0, sizeof pre);
int f = 1;
for(int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
if(find1(a) == find1(b)) f = 0;
if(pre[a] == 0) pre[a] = b;
else unite(pre[a], b);
if(pre[b] == 0) pre[b] = a;
else unite(pre[b], a);
}
if(! f) printf("Scenario #%d:\nSuspicious bugs found!\n", ++x);
else printf("Scenario #%d:\nNo suspicious bugs found!\n", ++x);
printf("\n");
}
return 0;
}