食物链 并查集 代码(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