食物链
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了食物链相关的知识,希望对你有一定的参考价值。
题目描述
动物王国中有三类动物 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 句话有的是真
的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
? 当前的话与前面的某些真的话冲突,就是假话
? 当前的话中 X 或 Y 比 N 大,就是假话
? 当前的话表示 X 吃 X,就是假话
你的任务是根据给定的 N 和 K 句话,输出假话的总数。
输入输出格式
输入格式:
从 eat.in 中输入数据
第一行两个整数,N,K,表示有 N 个动物,K 句话。
第二行开始每行一句话(按照题目要求,见样例)
输出格式:
输出到 eat.out 中
一行,一个整数,表示假话的总数。
我们并不需要知道他到底是哪一种动物。。。只需要各个动物之间的相对关系即可。
那么,就是加权并查集。。。
那么有那么几种操作:
判断:
1.A与B之间关系已知,则需判断给定关系是否与之冲突。
2.未知,则按照给定关系合并。
1 #include<cstdio> 2 inline int read() 3 { 4 int f=1,ans=0;char c=getchar(); 5 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 6 while(c>=‘0‘&&c<=‘9‘){ans=ans*10+c-‘0‘;c=getchar();} 7 return f*ans; 8 } 9 const int mod=3; 10 const int MAXN=5e4+1; 11 int f[MAXN],d[MAXN],n; 12 int dis(int x,int y) 13 { 14 return (d[x]-d[y]+mod)%mod; 15 } 16 int find(int x) 17 { 18 int odf=f[x]; 19 if(x!=f[x]) 20 { 21 f[x]=find(f[x]); 22 d[x]=(d[x]+d[odf]+mod)%mod; 23 }//return x; 24 return f[x]; 25 } 26 int jud(int z,int a,int b) 27 { 28 find(a);find(b); 29 if(a>n||b>n||(z==2&&a==b))return 1; 30 if(find(a)==find(b)) 31 { 32 if(z==1&&d[a]!=d[b])return 1; 33 if(z==2&&dis(a,b)!=1)return 1; 34 return 0; 35 } 36 int dx=(z==1?0:1); 37 /* 38 f[f[b]]=f[a]; 39 d[f[b]]=(d[a]-d[b]-dx+mod)%mod; 40 */ 41 d[f[a]]=(mod-d[a])%mod; 42 f[f[a]]=a; 43 f[a]=b;d[a]=dx; 44 d[f[b]]=(mod-d[b])%mod; 45 f[f[b]]=b; 46 f[b]=b;d[b]=0; 47 return 0; 48 } 49 int main() 50 { 51 n=read(); 52 for(int i=1;i<=n;i++){f[i]=i;} 53 int k=read(),ans=0; 54 for(int i=1,a,b,c;i<=k;i++) 55 { 56 c=read();a=read();b=read(); 57 ans+=jud(c,a,b); 58 } 59 printf("%d\n",ans); 60 return 0; 61 }
在重构f[b]与f(a)的关系时,可以用“取反”,即将a与f(a),b与f(b)的关系倒置。
这样可以避免复杂新距离的计算。
以上是关于食物链的主要内容,如果未能解决你的问题,请参考以下文章
带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代