NOI2001食物链
描述
动物王国中有三类动物 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。
输出格式
只有一个整数,表示假话的数目。
限制
1S
提示
并查集
对样例的解释
输入文件 对7句话的分析
100 7
1 101 1 假话
2 1 2 真话
2 2 3 真话
2 3 3 假话
1 1 3 假话
2 3 1 真话
1 5 5 真话
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<stack> 10 #include<string> 11 #include<algorithm> 12 #define maxn 150000+50 13 #define inf 0x7fffffff 14 #define xiao 1e-9 15 using namespace std; 16 int fa[maxn],p[maxn],n,m; 17 void prepared()//初始化 18 { 19 for(int i=1;i<=n*3;++i) p[i]=i; 20 for(int i=1;i<=n;++i) 21 { 22 fa[i]=i+n; 23 fa[i+n]=i+2*n; 24 fa[i+2*n]=i; 25 } 26 } 27 int find(int x)//每个动物群的代表元素 28 { 29 if(p[x]!=x) p[x]=find(p[x]); 30 return p[x]; 31 } 32 void work() 33 { 34 int ans=0; 35 int q,x,y; 36 scanf("%d",&m); 37 for(int i=1;i<=m;++i) 38 { 39 scanf("%d%d%d",&q,&x,&y); 40 if(x>n||y>n) {ans++;continue;} 41 int a[3],b[3];//a,b为两种动物维护的三个域 42 a[0]=find(x),b[0]=find(y);//代表元素 43 a[1]=fa[a[0]],a[2]=fa[a[1]];//a[1]为这种动物的被吃域,a[2]为吃域 44 b[1]=fa[b[0]],b[2]=fa[b[1]];//同上 45 bool flag=false; 46 for(int i=0;i<3;++i) 47 { 48 if(a[0]==b[i]) {flag=true;break;}//是否在一个环内 49 } 50 if(q==1) 51 { 52 if(flag) 53 { 54 if(a[0]!=b[0]) ans++;//如果代表元素不同说明不是一类,此话为假 55 } 56 else 57 { 58 for(int i=0;i<3;++i) p[b[i]]=a[i];//合并操作 59 } 60 } 61 else 62 { 63 if(x==y) {ans++;continue;} 64 if(flag==true) 65 { 66 if(fa[b[0]]!=a[0]) ans++;//如果b的被吃对象不是 a,此话为假 67 } 68 else 69 {for(int i=0;i<3;++i) p[b[i]]=a[(i+2)%3];}//等价于{p[b[0]]=a[2];p[b[1]]=a[0];p[b[2]]=a[1];} 70 } 71 } 72 cout<<ans; 73 } 74 int main() 75 { 76 scanf("%d",&n); 77 prepared(); 78 work(); 79 return 0; 80 }