Advanced Data Structures :: Disjoint Set
Description
一道灰常和谐的gay问题。
两只小虫走得比较近,就说明他们有关系。
但是如果出现形如三角恋的关系,就说明其中必然有一对gay。
你要做的就是检测小虫子间是否有gay的出现。
Type
Advanced Data Structures :: Disjoint Set
Analysis
利用mod2的加权并查集来解决。
假设每对在一起的小虫子都是异性,
合并前检查两只小虫的性别,查看是否有问题即可。
Solution
// POJ 2492
// A Bug's Life
// by A Code Rabbit
#include <cstdio>
#include <cstring>
const int MAXN = 2002;
const int MOD = 2;
struct DisjointSet {
int p[MAXN];
int w[MAXN];
void Init(int);
void Make(int x) { p[x] = x; }
int Find(int x) {
if (p[x] == x) return x;
int res = Find(p[x]);
w[x] = (w[x] + w[p[x]]) % MOD;
return p[x] = res;
}
void Union(int x, int y, int d) {
int px = Find(x); int py = Find(y);
p[px] = py;
w[px] = (w[y] - w[x] + d + MOD) % MOD;
}
};
void DisjointSet::Init(int n) {
memset(w, 0, sizeof(w));
for (int i = 0; i < n; i++) Make(i);;
}
int n, m;
DisjointSet set;
bool is_gay;
int main() {
int tot_case;
bool is_first = true;
scanf("%d", &tot_case);
for (int t = 0; t < tot_case; t++) {
scanf("%d%d", &n, &m);
set.Init(n);
is_gay = false;
for (int i = 0; i < m; i++) {
int x, y;
scanf("%d%d", &x, &y);
if (is_gay) continue;
int px = set.Find(x - 1);
int py = set.Find(y - 1);
if (px == py) {
if (set.w[x - 1] == set.w[y - 1])
is_gay = true;
} else {
set.Union(x - 1, y - 1, 1);
}
}
printf("Scenario #%d:\n", t + 1);
puts(is_gay ? "Suspicious bugs found!" : "No suspicious bugs found!");
puts("");
}
return 0;
}