编程算法 - 食物链 并查集 代码(C)
Posted clnchanpin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编程算法 - 食物链 并查集 代码(C)相关的知识,希望对你有一定的参考价值。
食物链 并查集 代码(C)
本文地址: http://blog.csdn.net/caroline_wendy
题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种. 已知A吃B, B吃C, C吃A.
按顺序给出两种信息K条.
第一种: x和y属于同一类.
另外一种: x吃y.
信息之间可能会出错和矛盾, 求不对的信息数.
比如:
有N=10仅仅动物, 给定K=7条信息.
(1) 1: x=101, y=1; 出错:没有101的动物.
(2) 2: x=1, y=2; 动物1吃动物2.
(3) 2: x=2, y=3; 动物2吃动物3.
(4) 2: x=3, y=3; 出错, 动物3不能吃动物3.
(5) 1: x=1, y=3; 出错, 动物1和动物3属于同一种, 与(2)(3)矛盾.
(6) 2: x=3, y=1; 动物3吃动物1.
(7) 1: x=5, y=5; 动物5和动物5属于同一种.
result = 3, 即(1)(4)(5)出错.
使用并查集(disjoint set)求解.
创建3*N个元素的并查集.每一组表示元素i可能属于的种类x, 共3种.
然后合并并查集. 找到矛盾信息.
代码:
/* * main.cpp * * Created on: 2014.7.20 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> /* * main.cpp * * Created on: 2014.7.20 * Author: spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <memory.h> #include <limits.h> #include <algorithm> using namespace std; class DisjoinSet { static const int MAX_N = 10000; int par[MAX_N]; int rank[MAX_N]; public: void init(int n) { for (int i=0; i<n; i++) { par[i] = i; rank[i] = 0; } } int find (int x) { if(par[x] == x) { return x; } else { return par[x] = find(par[x]); } } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) return; if (rank[x] < rank[y]) { par[x] = y; } else { par[y] = x; if (rank[x] == rank[y]) rank[x]++; } } bool same(int x, int y) { return find(x) == find(y); } }; class Program { static const int MAX_N = 100; int N = 100, K = 7; int T[MAX_N] = {1, 2, 2, 2, 1, 2, 1}, X[MAX_N] = {101, 1, 2, 3, 1, 3, 4}, Y[MAX_N] = {1, 2, 3, 3, 3, 1, 4}; DisjoinSet DS; public: void solve() { DS.init(N*3); int ans = 0; for (int i=0; i<K; i++) { int t = T[i]; int x = X[i]-1, y = Y[i]-1; if (x<0 || N<=x || y<0 || N<=y) { ans ++; continue; } if (t==1) { if (DS.same(x, y+N) || DS.same(x, y+2*N)) { ans++; } else { DS.unite(x, y); DS.unite(x+N, y+N); DS.unite(x+N*2, y+N*2); } } else { if (DS.same(x,y) || DS.same(x, y+2*N)) { ans++; } else { DS.unite(x, y+N); DS.unite(x+N, y+2*N); DS.unite(x+2*N, y); } } } printf("ans = %d\n", ans); } }; int main(void) { Program iP; iP.solve(); return 0; }
输出:
ans = 3
以上是关于编程算法 - 食物链 并查集 代码(C)的主要内容,如果未能解决你的问题,请参考以下文章
带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代