标签:code 否则 扩展 mes 判断 end div 一句话 style
# 题意
有三类动物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。
当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
根据给定的N和K句话,输出假话的总数。
# 题解
将每个动物拆成3个点,同类Xself,捕食Xeat和天敌Xenemy
x和y是同类即x和y的捕食一样,天敌一样,同类一样
合并xself和yself,xeat和yeat,xenemy和yenemy
若x吃y则,x的天敌是y的捕食,x捕食y的同类,x同类是y天敌
合并xeat和yself,合并xenemy和yeat,合并xself和yenemy
判断矛盾:
若x和y是同类
1)xeat和yself是同一个集合说明x吃y矛盾
2)xself和yeat在同一个集合说明y吃x矛盾
x吃y:
1)若xself和yself在同一个集合证明x和y是同类矛盾
2)若xself和yeat在一个集合说明y吃x矛盾
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int P=5e4+10,N=P*3; 4 int fa[N]; 5 int n,m; 6 int find(int x){ 7 if(fa[x]==x) return x; 8 return fa[x]=find(fa[x]); 9 } 10 void merge(int a,int b){ 11 fa[find(a)]=find(b); 12 } 13 int main(){ 14 cin>>n>>m; 15 for(int i=0;i<=n*3;i++){ 16 fa[i]=i; 17 } 18 int ans=0; 19 for(int i=0;i<m;i++){ 20 int op,x,y; 21 cin>>op>>x>>y; 22 23 if(x>n || y>n){ 24 ans++; 25 continue; 26 } 27 28 int x_self=x,x_eat=x+n,x_enemy=x+2*n; 29 int y_self=y,y_eat=y+n,y_enemy=y+2*n; 30 31 if(op==1){ 32 if(find(x_self)==find(y_eat) || find(x_eat)==find(y_self)) { 33 ans++; 34 } 35 else { 36 merge(x_eat, y_eat); 37 merge(x_enemy, y_enemy); 38 merge(x_self, y_self); 39 } 40 } 41 else { 42 if(find(x_self)==find(y_eat) || x==y || find(x_self)==find(y_self)){ 43 ans++; 44 } 45 else { 46 merge(x_eat, y_self); 47 merge(x_enemy, y_eat); 48 merge(x_self, y_enemy); 49 } 50 } 51 } 52 cout<<ans<<endl; 53 }
标签:code 否则 扩展 mes 判断 end div 一句话 style
原文地址:https://www.cnblogs.com/hhyx/p/12452010.html