POJ 1182 食物链(种类并查集)
题目:http://poj.org/problem?id=1182
#include <iostream> using namespace std; const int M = 50000 + 10; struct Node { int father; int kind; }node[M]; void Init(int n) { for (int i = 1; i <= n; i++) { node[i].father = i; node[i].kind = 0; } } // int Find(int x) { if (x == node[x].father) { return x; } int temp = node[x].father;//temp保存原来的老爸 node[x].father = Find(node[x].father); node[x].kind = (node[x].kind + node[temp].kind) % 3;////////////// return node[x].father; } // void Union(int rootx, int rooty, int x, int y, int k)//k == 0:a==b k == 1:a > b { node[rooty].father = rootx; node[rooty].kind = (-k +(node[x].kind - node[y].kind)+3)%3;/////////////// } //(node[a].kind - node[b].kind + 3) % 3 == 1表示a > b //node[a].kind == node[b].kond 表示 a == b //为了方便操作根结点的种类是0 //与根结点直接相连的节点与根结点的关系是正确的 //在同一颗树上的结点表示存在关系 int main() { int n, m; scanf("%d%d", &n, &m);//这题只有一组数据 int ans = 0; Init(n); while (m--) { int kind, a, b; scanf("%d%d%d", &kind, &a, &b); if (a > n || b > n) { ans++; continue; } if (kind == 2 && a == b) { ans++; continue; } int roota = Find(a); int rootb = Find(b); if (roota != rootb) { Union(roota, rootb, a, b, kind - 1); } else { if (kind == 1 && node[a].kind != node[b].kind) { ans++; } if (kind == 2 && (node[a].kind - node[b].kind + 3) % 3 != 1) { ans++; } } } printf("%d\n", ans); return 0; }
posted on 2012-08-31 20:09 [S*I]SImMon_WCG______* 阅读(199) 评论(0) 编辑 收藏 举报