并查集的经典题型,POJ上题目还是中文= =,一般看到中文题都会感觉不太简单,这道题的数学归纳用得比较多,可以简化代码,挺有意思的。
同类型的题目还有POJ1703,比这个要简单,想了解并查集基本介绍或想参考Code请移步:算法手记 之 数据结构(并查集详解)(POJ1703)
存在食物链: A吃B,B吃C,C吃A
给出两种判断:1 a b 指a和b相同
2 a b 指a吃b
现依照题目输入,输出判断的错误次数:1.a,b超过N错误
2.a,b不符合前面判断则错误
Code仅供参考:
1 //食物链:A吃B,B吃C,C吃A 2 //r[]中:0为同类,1为父亲吃自己,2为自己吃父亲 3 //Time:204Ms Memory:556K 4 #include<iostream> 5 #include<cstring> 6 #include<cstdio> 7 using namespace std; 8 #define MAX 50005 9 int n, k; 10 int fa[MAX], r[MAX]; //father node - ralation 11 int fake; //假话总数 12 int find(int x) 13 { 14 if (x != fa[x]) 15 { 16 int tmp = fa[x]; 17 fa[x] = find(fa[x]); //压缩路径 18 r[x] = (r[x] + r[tmp]) % 3; //归纳得出 19 } 20 return fa[x]; 21 } 22 int main() 23 { 24 scanf("%d%d", &n, &k); 25 26 for (int i = 1; i <= n; i++) 27 fa[i] = i; //将父结点设为自己 28 for (int i = 0; i < k; i++) 29 { 30 int flag, a, b; 31 scanf("%d%d%d", &flag, &a, &b); 32 if (a > n || b > n) 33 { 34 fake++; 35 continue; 36 } 37 int pa = find(a), pb = find(b); 38 if (flag == 1) 39 { 40 if (pa != pb) 41 { 42 fa[pa] = pb; 43 r[pa] = (r[b] - r[a] + 3) % 3; //归纳得出 44 } 45 else if (r[a] != r[b]) 46 fake++; 47 } 48 else { 49 if (pa != pb) { 50 fa[pa] = pb; 51 r[pa] = (r[b] - r[a] + 3) % 3 + 1; //归纳得出 52 } 53 else if ((r[a] - r[b] + 3) % 3 != 1) //归纳得出 54 fake++; 55 } 56 } 57 printf("%d\n", fake); 58 return 0; 59 }