P2024 [NOI2001] 食物链
题目描述
动物王国中有三类动物A,B,CA,B,CA,B,C,这三类动物的食物链构成了有趣的环形。AAA吃BBB,BBB吃CCC,CCC吃AAA。
现有NNN个动物,以1∼N1 \sim N1∼N编号。每个动物都是A,B,CA,B,CA,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这NNN个动物所构成的食物链关系进行描述:
- 第一种说法是
1 X Y,表示XXX和YYY是同类。 - 第二种说法是
2 X Y,表示XXX吃YYY。
此人对NNN个动物,用上述两种说法,一句接一句地说出KKK句话,这KKK句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
- 当前的话与前面的某些真的话冲突,就是假话;
- 当前的话中XXX或YYY比NNN大,就是假话;
- 当前的话表示XXX吃XXX,就是假话。
你的任务是根据给定的NNN和KKK句话,输出假话的总数。
输入格式
第一行两个整数,N,KN,KN,K,表示有NNN个动物,KKK句话。
第二行开始每行一句话。格式见题目描述与样例。
输出格式
一行,一个整数,表示假话的总数。
输入输出样例 #1
输入 #1
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5输出 #1
3说明/提示
对于全部数据,1≤N≤5×1041\le N\le 5 \times 10^41≤N≤5×104,1≤K≤1051\le K \le 10^51≤K≤105。
C++实现
#include<cstdio>inlineintread(){charc=getchar();intn=0;while(c<'0'||c>'9'){c=getchar();}while(c>='0'&&c<='9'){n=(n<<1)+(n<<3)+(c&15);c=getchar();}returnn;}constintmaxN=100005;intn,m,ans,fa[maxN*3];intfind(intu){returnfa[u]==u?u:fa[u]=find(fa[u]);}intmain(){n=read(),m=read();for(inti=1;i<=n*3;i++){fa[i]=i;}for(;m;m--){intopt=read(),u=read(),v=read();if(u>n||v>n){ans++;continue;}if(opt==1){if(find(u+n)==find(v)||find(u)==find(v+n)){ans++;}else{fa[find(u)]=find(v);fa[find(u+n)]=find(v+n);fa[find(u+n+n)]=find(v+n+n);}}else{if(find(u)==find(v)||find(u)==find(v+n)){ans++;}else{fa[find(u+n)]=find(v);fa[find(u+n+n)]=find(v+n);fa[find(u)]=find(v+n+n);}}}printf("%d\n",ans);return0;}后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容