POJ 1182并查集的经典运用
2013-10-01 20:18
295 查看
tag的取值:1表示x吃px,-1表示px吃x,0表示x与px同类
#include <iostream> #include <vector> #include <cmath> using namespace std; typedef struct { int parent; int tag; }Node; vector<Node> nodes; int n, k; void MakeSet() { nodes.resize( n+10 ); for(int i = 0; i < nodes.size(); ++i) { nodes[i].parent = i; nodes[i].tag = 0; } } int FindSet(int index, int& steps) { if( nodes[index].parent == index ) return index; else { steps += nodes[index].tag; nodes[index].parent = FindSet( nodes[index].parent, steps ); steps %= 3; switch( steps ) { case -2: nodes[index].tag = 1; break; case 2: nodes[index].tag = -1; break; default: nodes[index].tag = steps; } return nodes[index].parent; } } void Union(int r1, int r2, int t) { nodes[r2].parent = r1; nodes[r2].tag = t; } int main() { cin >> n >> k; MakeSet(); int ans = 0; for(int i = 0; i < k; ++i) { int t, x, y; cin >> t >> x >> y; if( x > n || y > n ) ++ans; else if(t == 2 && x == y) ++ans; else { int d1 = 0, d2 = 0; int r1 = FindSet(x, d1); int r2 = FindSet(y, d2); if( r1 == r2 ) { if(nodes[x].tag == nodes[y].tag && t != 1) ++ans; if(t == 2) { int t1 = nodes[x].tag; int t2 = nodes[y].tag; if( (t1==-1&&t2==0) || (t1==-1&&t2==1) || (t1==1&&t2==-1) ) ++ans; } } else { int d = nodes[x].tag - 1 - nodes[y].tag; if( d <= -2 ) d += 3; else if( d >= 2 ) d -= 3; Union(r1, r2, d); } } } cout << ans << endl; return 0; }
tag为-1,0,1时,代码写起来挺费劲的。借鉴了网上的代码,将tag的取值改为0,1,2;其中2表示px吃x,0,1取值含义保持不变
#include <iostream> #include <vector> #include <cstdio> using namespace std; class Node { public: int parent; int link; int rank; Node(int p=0, int l=0, int r=0):parent(p), link(l), rank(r){ }; }; vector<Node> nodes; int n, k; void MakeSet() { nodes.resize( n+1 ); for(int i = 1; i <= n; ++i) nodes[i] = Node(i) ; } int FindSet(int i) { if( nodes[i].parent == i ) return i; int p = nodes[i].parent; nodes[i].parent = FindSet( nodes[i].parent ); nodes[i].link = (nodes[i].link + nodes[p].link)%3; return nodes[i].parent; } void Union(int x, int y, int link) { int rx = FindSet(x); int ry = FindSet(y); if( nodes[rx].rank < nodes[ry].rank ) { nodes[rx].parent = ry; nodes[rx].link = (3 - nodes[x].link + link + nodes[y].link)%3; } else { nodes[ry].parent = rx; if( nodes[rx].rank == nodes[ry].rank ) nodes[rx].rank += 1; nodes[ry].link = (6 - nodes[y].link - link + nodes[x].link)%3; } } int main() { int ans = 0; scanf("%d%d", &n, &k); MakeSet(); for(int i = 0; i < k; ++i) { int l, x, y; scanf("%d%d%d", &l, &x, &y); --l; if(x > n || y > n) ++ans; else if(l == 1 && x == y) ++ans; else if( FindSet(x) == FindSet(y) ) { if( (l+nodes[y].link)%3 != nodes[x].link ) ++ans; } else { Union(x, y, l); } } printf("%d\n", ans); return 0; }
相关文章推荐
- POJ-1182-食物链(并查集经典题)
- poj 1182 食物链 (并查集 经典)
- poj 1182 【经典并查集】 和【不一样的解法】
- POJ1182 食物链(经典并查集)
- POJ1182--食物链(经典并查集)并查集看不出来系列2
- POJ1182-食物链(经典并查集)
- POJ 1182 食物链(经典并查集)
- 【解题报告】 POJ 1182 食物链 并查集的经典应用+相对位置
- POJ - 1182 食物链 并查集经典
- poj 1182 带权并查集经典
- poj 1182 并查集经典题…
- poj1182 一道比较经典的并查集
- POJ 1182 食物链【经典并查集应用】
- poj1182 并查集经典题 Weighted Union-Find Sets
- poj 1182 食物链 (种类并查集经典题)
- POJ 1182食物链(经典的并查集)
- POJ-1182 食物链 经典并查集
- poj 1182 食物链(经典并查集)
- poj1182 食物链 种类并查集 经典题
- POJ-1182 食物链(经典并查集)