题目链接:食物链
这题是带权并查集的经典题,用rank[i]表示i与i父亲的关系,0为同类,1为吃,2为被吃。
rank在压缩路径和合并过程的转化在纸上把所有情况归纳出来,就可以变成一个公式。
代码:
#include <stdio.h> #include <string.h> const int N = 50005; int n, k, parent[N], rank[N], ans = 0; int find(int x) { if (parent[x] == x) return x; else { int p = find(parent[x]); rank[x] = (rank[x] + rank[parent[x]]) % 3; parent[x] = p; } return parent[x]; } int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { parent[i] = i; rank[i] = 0; } while (k--) { int q, a, b; scanf("%d%d%d", &q, &a, &b); if (a > n || b > n || (q == 2 && a == b)) ans++; else { int pa = find(a), pb = find(b); if (pa == pb) { if ((rank[b] - rank[a] + 3) % 3 != q - 1) ans++; } else { parent[pb] = pa; rank[pb] = (rank[a] - rank[b] + q + 2) % 3; } } } printf("%d\n", ans); return 0; }
POJ 1182 食物链(带权并查集),布布扣,bubuko.com
原文:http://blog.csdn.net/accelerator_/article/details/23765775