食物链 - 洛谷【2024】
题目描述
题目描述
动物王国中有三类动物 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 中
一行,一个整数,表示假话的总数。
输入输出样例
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
3
说明
1 ≤ N ≤ 5 ∗ 10^4
1 ≤ K ≤ 10^5
题目分析
对于那种自己吃自己或者超出n的大小的
可以直接判断知道错误
然后i++再做下一次循环
如果两个条件都不满足 就判断这个是否和前面的话冲突
这里有一个公式
dis=x1-x2+x3
x1是x到父节点的距离 x2是y到父节点的距离
x3是题目中给的那个p 用这个公式来求两条不相连的路之间的距离
如果说两个点有关系 则需要将两个点的祖先节点合并到一起
如果给的数据(要判断是否冲突的)已经合并到一起了
就判断一下是否正确
这里用了一下 dis[x]-dis[y] 用它和t之间的关系 可以判断是否正确
最后就输出ans就可以了
错误
1.find函数未路径压缩 和 节点的距离进行压缩
如果不这样做的话 y与父节点的距离就得不到全部的更新
2.p没减1
因为自己定义的是0是同类 1是吃 2是被吃 和 题目中的1 2 正好多1
所以在求距离的时候 p要减1 才能求出正确的距离
3.给dis[x]dis[y]赋值
如果这样的话 dis[x]和dis[y]的值每一次循环的时候都会被附上1或者2
其实dis里面所有变量的值都在求距离的时候求出来了
所以无需对dis里面赋值
4.%3
可能加上p后的值要大于3 也有可能求出距离是负数
所以要加上3 %3 要保证距离是0 1 2中的一个
源代码
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 int find(int); 7 void hb(int,int); 8 int n,k,p,x,y,u,ans=0,father[50005],dis[50005]; 9 int main() 10 { 11 // freopen("2024.txt","r",stdin); 12 scanf("%d%d",&n,&k); 13 for(int i=1;i<=n;i++) 14 father[i]=i; 15 memset(dis,0,sizeof(dis)); 16 for(int i=1;i<=k;i++) 17 { 18 scanf("%d%d%d",&p,&x,&y); 19 if(x>n||y>n) 20 { 21 ans++; 22 continue; 23 } 24 if(p==2&&x==y) 25 { 26 ans++; 27 continue; 28 } 29 else 30 { 31 int r3,r4; 32 r3=find(x); 33 r4=find(y); 34 if(r3!=r4) 35 { 36 int u=dis[y]; 37 hb(r3,r4); 38 dis[r4]=(dis[x]-u+p-1+3)%3; 39 } 40 else 41 if(x!=y) 42 { 43 int t=(3+dis[x]-dis[y])%3; 44 if(p==1&&t!=0) 45 { 46 ans++; 47 continue; 48 } 49 if(p==2&&t!=2) 50 ans++; 51 } 52 } 53 } 54 printf("%d",ans); 55 return 0; 56 } 57 int find(int m) 58 { 59 if(father[m]!=m) 60 { 61 int kk=father[m]; 62 father[m]=find(father[m]); 63 dis[m]=(dis[m]+dis[kk])%3; 64 } 65 return father[m]; 66 } 67 void hb(int b,int d) 68 { 69 int r1,r2; 70 r1=find(b); 71 r2=find(d); 72 father[r2]=r1; 73 }

浙公网安备 33010602011771号