题目链接
http://poj.org/problem?id=1182
分析
由于吃与被吃关系构成了一个环,所以我们可以用扩展域并查集来维护关系;
对于每种动物,建三个节点分别保存自身,能吃的与会被吃的。
AC代码
#include <cstdio>
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int maxn = 5e4 + 5;
int f[3 * maxn];
int find(int x) {
if (x == f[x]) return x;
return f[x] = find(f[x]);
}
inline void merge(int a, int b) {
a = find(a), b = find(b);
f[a] = b;
}
int main() {
int n = read(), k = read(), cnt = 0;
for (int i = 1; i <= 3 * n; ++i) f[i] = i;
while (k--) {
int d = read(), x = read(), y = read();
if (x > n || y > n || (d == 2 && x == y)) ++cnt;
else if (d == 1) {
if (find(x) == find(y + n) || find(y) == find(x + n)) ++cnt;
else merge(x, y), merge(x + n, y + n), merge(x + 2 * n, y + 2 * n);
}
else if (d == 2) {
if (find(x) == find(y) || find(x) == find(y + n)) ++cnt;
else merge(x, y + 2 * n), merge(x + n, y), merge(x + 2 * n, y + n);
}
}
printf("%d", cnt);
return 0;
}