思路:保存每个点与其父节点的关系,注意合并和路径压缩即可。
AC代码
#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 2000 + 5;
struct node{
int par;
int real; //0表示同性,1表示性别相异
}a[maxn];
int find(int x, int &root) {
if(a[x].par == x) {
root = x;
return a[x].real;
}
int r = (a[x].real + find(a[x].par, root)) % 2;
a[x].par = root;
return a[x].real = r;
}
bool unionset(int x, int y) {
int r1, r2;
int rx = find(x, r1), ry = find(y, r2);
if(r1 == r2) {
if(rx == ry) return false;
}
else {
a[r1].par = y;
a[r1].real = (rx + 1) % 2;
}
return true;
}
int main() {
int n, m, T, kase = 1;
scanf("%d", &T);
while(T--) {
if(kase > 1) printf("\n");
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; ++i) {
a[i].par = i;
a[i].real = 0;
}
int x, y;
int flag = 1;
for(int i = 0; i < m; ++i) {
scanf("%d%d", &x, &y);
if(flag && !unionset(x, y)) {
flag = 0;
}
}
printf("Scenario #%d:\n", kase++);
if(flag) printf("No suspicious bugs found!\n");
else printf("Suspicious bugs found!\n");
}
return 0;
}
如有不当之处欢迎指出!