http://poj.org/problem?id=1182
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 77012 | Accepted: 22912 |
Description
动物王国中有三类动物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个动物,以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),输出假话的总数。
Input
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
Output
只有一个整数,表示假话的数目。
Sample Input
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
Sample Output
3
Source
详解参考、、唉,不献丑了、
1 #include <algorithm> 2 #include <cstdio> 3 4 using namespace std; 5 6 const int N(50005); 7 struct Node 8 { 9 int fa,relation; 10 }ani[N]; 11 12 int find(int x) 13 { 14 if(ani[x].fa==x) return x; 15 int dad=ani[x].fa; 16 ani[x].fa=find(dad); 17 ani[x].relation=(ani[x].relation+ani[dad].relation)%3; 18 return ani[x].fa; 19 } 20 21 inline void read(int &x) 22 { 23 x=0;register char ch=getchar(); 24 for(;ch<'0'||ch>'9';) ch=getchar(); 25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; 26 } 27 28 int main() 29 { 30 int k,n,ans=0; read(n),read(k); 31 for(int i=1;i<=n;i++) ani[i].fa=i; 32 for(int d,x,y;k--;) 33 { 34 read(d),read(x),read(y); 35 if(x>n||y>n) ans++; 36 else if(d==2&&x==y) ans++; 37 else 38 { 39 int fx=find(x),fy=find(y); 40 if(fx!=fy) 41 { 42 ani[fy].fa=fx; 43 ani[fy].relation=(3-ani[y].relation+d-1+ani[x].relation)%3; 44 } 45 else 46 { 47 if(d==1) 48 { 49 if(ani[x].relation!=ani[y].relation) ans++; 50 } 51 else if((ani[y].relation+3-ani[x].relation)%3!=1) ans++; 52 } 53 } 54 } 55 printf("%d ",ans); 56 return 0; 57 }