1390:食物链【NOI2001】

简介: 1390:食物链【NOI2001】

1390:食物链【NOI2001】

时间限制: 1000 ms         内存限制: 65536 KB

【题目描述】

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。

现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。

有人用两种说法对这N个动物所构成的食物链关系进行描述:

第一种说法是"1 X Y",表示X和Y是同类。

第二种说法是"2 X Y",表示X吃Y。

此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

1)当前的话与前面的某些真的话冲突,就是假话;

2)当前的话中X或Y比N大,就是假话;

3)当前的话表示X吃X,就是假话。

你的任务是根据给定的N(1≤ N ≤50,000)和K句话(0≤K≤100,000),输出假话的总数。

【输入】

第一行是两个整数N和K,以一个空格分隔。

以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。

若D=1,则表示X和Y是同类。

若D=2,则表示X吃Y。

【输出】

只有一个整数,表示假话的数目。

【输入样例】

100 7

1 101 1

2 1 2

2 2 3

2 3 3

1 1 3

2 3 1

1 5 5

【输出样例】

3

【提示】

【样例解释】

 

1. //示例代码
2. #include <iostream>
3. #include <cstdio>
4. using namespace std;
5. 
6. const int N=150005;   // 定义常量 N,表示数组大小
7. int n,k,F;           // n 表示点的数量,k 表示操作数, F 表示不合法的操作数。
8. int f[N];            // 数组 f 存储点的祖先
9. 
10. // 并查集中的查找操作,实现路径压缩
11. int find(int x){
12. if(f[x]==x) return f[x];
13. return f[x]=find(f[x]);
14. }
15. 
16. // 并查集中的合并操作
17. void unionn(int x,int y){
18.     x=find(x);
19.     y=find(y);
20. if(x!=y) f[y]=x;
21. }
22. 
23. int main()
24. {
25. scanf("%d %d",&n,&k);  // 输入点的数量和操作数
26. for(int i=1;i<=n*3;i++)f[i]=i;  // 初始化并查集,每一个点是其自己的祖先。
27. 
28. int d,x,y;   // d 表示每个操作的类型,x、y 表示需要连接的两个点的编号。
29. while(k--){
30. scanf("%d %d %d",&d,&x,&y);
31. if(x>n||y>n){  // 判断输入的点是否合法。如果一个点的编号大于 n,代表这个操作是不合法的。
32.             F++; continue;
33.         }
34. else if(d==1){   // 如果操作类型为 1,x,y为同类
35. if(find(x)==find(y+n) || find(x)==find(y+n*2))  
36.                 F++; // 如果x的猎物是y或y的天敌  为假
37. else{  // 否则,合并。
38. unionn(x,y);//同类合并
39. unionn(x+n,y+n);//x的天敌和y的天敌是同类
40. unionn(x+2*n,y+2*n);//x的猎物也和y的猎物是同类
41.             }    
42.         }
43. else if(d==2){   // 如果操作类型为 2,x的猎物是y。
44. if(find(x)==find(y) || find(x)==find(y+n*2))  
45.                 F++; // 如果x,y同类 或 x的天敌是y  则假。
46. else{  // 否则,合并。
47. unionn(x,y+n);//x的猎物是y
48. unionn(x+n,y+2*n);//x的天敌也是y的猎物
49. unionn(x+2*n,y);//y的天敌是x
50.             }    
51.         }
52.     }
53. printf("%d",F);   // 输出不合法操作的数量。
54. return 0;
55. }


相关文章
|
6月前
|
算法
【随想】每日两题Day.9
【随想】每日两题
36 1
|
6月前
【随想】每日两题Day.17
【随想】每日两题Day.17
39 0
|
6月前
|
机器学习/深度学习 NoSQL Shell
【随想】每日两题Day.13
【随想】每日两题Day.13
29 0
|
6月前
|
算法
【随想】每日两题Day.1
【随想】每日两题Day.1
33 0
|
6月前
【随想】每日两题Day.2
随想】每日两题Day.2
23 0
|
6月前
【随想】每日两题Day.18
【随想】每日两题Day.18
41 0
|
6月前
【随想】每日两题Day.19
【随想】每日两题Day.19
36 0
|
6月前
|
存储
【随想】每日两题Day.21
【随想】每日两题Day.21
39 0
|
6月前
|
算法
【随想】每日两题Day.15
【随想】每日两题Day.15
34 0
|
6月前
【随想】每日两题Day.8
【随想】每日两题
35 0