poj1182
本文地址:https://www.cnblogs.com/maplefighting/p/9123814.html
题目名称:食物链
链接:http://poj.org/problem?id=1182
题意:中文题,自己看
思路:考察并查集。由于有三种动物,且不知种类,所以我们得分为三组i-A,i-B,i-C。i-X表示i属于种类X
若x和y同种,则合并x-A和y-A,x-B和y-B,x-C和y-C.
若x吃y,则合并x-A和y-B,x-B和y-C,x-C和y-A
代码如下:
1 #include<cstdio>
2 using namespace std;
3 const int MAX_K = 100005;
4 int n, k;
5 int f[50000 * 3 + 5];
6 void init(int n) {
7 for(int i = 0; i < n; i++){
8 f[i] = i;
9 }
10 }
11 int found(int x) {
12 return f[x] == x ? x : f[x] = found(f[x]);
13 }
14 void unite(int x,int y) {
15 x = found(x), y = found(y);
16 if(x != y){
17 f[x] = y;
18 }
19 return ;
20 }
21 bool same(int x,int y) {
22 return found(x) == found(y);
23 }
24 int main(){
25 scanf("%d%d", &n, &k);
26 init(n * 3);
27 int sum = 0;
28 while(k--) {
29 int d, x, y;
30 scanf("%d%d%d", &d, &x, &y);
31 x--; y--;
32 if(x < 0 || y < 0 || x >= n || y >= n) {
33 sum++;
34 continue;
35 }
36 if(d == 1) {
37 //x和y为同类,判断x吃y或者y吃x为假
38 if(same(x, y + n) || same(y, x + n)) {
39 sum++;
40 }
41 else {
42 unite(x, y);
43 unite(x + n, y + n);
44 unite(x + 2 * n, y + 2 * n);
45 }
46 }
47 else {
48 //x吃y,判断x和y同类,或者y吃x为假
49 if(same(x, y) || same(y, x + n)){
50 sum++;
51 }
52 else{
53 unite(x, y+n);
54 unite(x + n, y + 2 * n);
55 unite(x + 2 * n, y);
56 }
57 }
58 }
59 printf("%d\n",sum);
60 return 0;
61 }
本文版权归作者本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.