Advanced Data Structures :: Disjoint Set
Description
在一个奇葩世界里的奇葩环形食物链。
按题目给的信息构造出食物链,并且找出矛盾的信息数。
Type
Advanced Data Structures :: Disjoint Set
Analysis
一道经典的加权并查集题目,mod 3的。
因为太经典,也不知道讲啥……
就是合并前检查是否矛盾即可。
不过此题好似有个奇葩,只有一组输入数据。
如果认为是多组输入,以文件结尾来结束程序输入的话,就会悲剧。
Solution
// POJ 1182
// 食物链
// by A Code Rabbit
#include <cstdio>
#include <cstring>
const int MAXN = 50002;
const int MOD = 3;
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, k;
DisjointSet set;
int main() {
scanf("%d%d", &n, &k);
set.Init(n);
int ans = 0;
for (int i = 0; i < k; i++) {
int d, x, y;
scanf("%d%d%d", &d, &x, &y);
if (x > n || y > n) {
ans++;
continue;
}
int px = set.Find(x - 1);
int py = set.Find(y - 1);
if (px == py) {
if (d == 1 && set.w[x - 1] != set.w[y - 1])
ans++;
else if (d == 2 && (set.w[x - 1] - set.w[y - 1] + MOD) % MOD != 1)
ans++;
} else {
if (d == 1)
set.Union(x - 1, y - 1, 0);
if (d == 2)
set.Union(x - 1, y - 1, 1);
}
}
printf("%d\n", ans);
return 0;
}