食物链(poj1182)
食物链
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 57387 | Accepted: 16781 |
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
思路:并查集.详解翻阅挑战程序设计竞赛(第二版p89)
粗略的说下思路,每个动物有三种状态,分别用数字表示是i,i+p,i+2p;
如果i,j为同一种,则有i,j在同一集合,i+p与j+p同一集合,i+2p,j+2p 同一集合,
如果i吃j,就有i,j+p同一集合,i+p,j+2p同一集合,i+2p,j同一集合。
这样如果j,吃z,根据这样合并,就可以得到z,吃i;
那么每个询问判下是否矛盾就可以了。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdlib.h> 5 #include<string.h> 6 const int N=5*30005; 7 using namespace std; 8 int dian[3*N]; 9 int quan[3*N]; 10 int main(void) 11 { 12 int i,j,k,p,q; 13 int x1,x2,x3; 14 scanf("%d %d",&p,&q); 15 { 16 for(i=0; i<3*N; i++) 17 { 18 quan[i]=1; 19 dian[i]=i; 20 } 21 int cnt=0; 22 while(q--) 23 { 24 scanf("%d %d %d",&x1,&x2,&x3); 25 int xx1,yy1; 26 int xx2,yy2; 27 int xx3,yy3; 28 for(xx1=x2;dian[xx1]!=xx1;) 29 xx1=dian[xx1]; 30 for(yy1=x3;dian[yy1]!=yy1;) 31 yy1=dian[yy1]; 32 for(xx2=x2+p;xx2!=dian[xx2];) 33 xx2=dian[xx2]; 34 for(yy2=x3+p;yy2!=dian[yy2];) 35 yy2=dian[yy2]; 36 for(xx3=x2+2*p;xx3!=dian[xx3];) 37 xx3=dian[xx3]; 38 for(yy3=x3+2*p;yy3!=dian[yy3];) 39 yy3=dian[yy3]; 40 if(x2<=0||x3<=0||x2>p||x3>p) 41 { 42 cnt++; 43 } 44 else 45 {if(x1==1) 46 { 47 if(xx1!=yy1&&xx1!=yy2&&yy1!=xx2) 48 { 49 if(quan[xx1]>=quan[yy1]) 50 { 51 quan[xx1]+=quan[yy1]; 52 dian[yy1]=xx1; 53 quan[xx2]+=quan[yy2]; 54 dian[yy2]=xx2; 55 quan[xx3]+=quan[yy3]; 56 dian[yy3]=xx3; 57 } 58 else 59 { 60 quan[yy1]+=quan[xx1]; 61 dian[xx1]=yy1; 62 quan[yy2]+=quan[xx2]; 63 dian[xx2]=yy2; 64 quan[yy3]+=quan[xx3]; 65 dian[xx3]=yy3; 66 } 67 } 68 else if(xx1==yy1){continue;} 69 else cnt++; 70 } 71 if(x1==2) 72 { 73 if(xx1!=yy1&&xx1!=yy2&&yy1!=xx2) 74 { 75 if(quan[xx1]>=quan[yy2]) 76 { 77 quan[xx1]+=quan[yy2]; 78 dian[yy2]=xx1; 79 quan[xx2]+=quan[yy3]; 80 dian[yy3]=xx2; 81 quan[xx3]+=quan[yy1]; 82 dian[yy1]=xx3; 83 } 84 else 85 { 86 quan[yy2]+=quan[xx1]; 87 dian[xx1]=yy2; 88 quan[yy3]+=quan[xx2]; 89 dian[xx2]=yy3; 90 quan[yy1]+=quan[xx3]; 91 dian[xx3]=yy1; 92 } 93 } 94 else if(xx1==yy2) 95 { 96 continue; 97 } 98 else cnt++; 99 } 100 101 }}printf("%d\n",cnt); 102 103 } return 0;}
油!油!you@