当前位置:网站首页>E - 食物链

E - 食物链

2022-07-06 06:08:00 RCyyds

传送门:食物链
在这里插入图片描述
在这里插入图片描述
题意:题意简单,直接看题目即可。
思路:这是个经典的带权并查集题目了。
根据惯例,我们需要两个数组,一个是父亲节点数组p,另一个为记录x到p[x]的权值的d[x]数组,在这里规定x吃p[x]。
这道题的难点在于吃与被吃的数组d之间的关系
1.假如x与y是同类且用共同的祖宗节点,那么就判定d[x]-d[y])%3是否等于0,等于0就代表与所说的话一致,反之不一致,ans++;
2.假如x与y是同类且没用共同的祖宗节点,就让px的父亲节点为py,算出d[px],d[px]=d[y]-d[x];
3.假如x吃y且用共同的祖宗节点,那么就判定d[x]-d[y]-1)%3是否等于0,等于0就代表与所说的话一致,反之不一致,ans++;
4.假如x吃y且没用共同的祖宗节点,就让px的父亲节点为py,算出d[px],d[px]=d[y]-d[x]+1;
5.假如x,y大于n,ans++;
代码

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=5e4+5;
int p[N],d[N];
int find(int x)
{
	if(x!=p[x]) 
	{
		int t=find(p[x]);
		d[x]+=d[p[x]];
		p[x]=t;
	}
	return p[x];
}
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	for (int i = 1; i <= n; i ++ ) p[i] = i;
	int ans=0;
	while(k--)
	{
		int t,x,y;
		scanf("%d%d%d",&t,&x,&y);
		int px=find(x),py=find(y);
		if (x > n || y > n) ans ++ ;
		else
		{
			if(t==1)
			{
				if(px==py&&(d[x]-d[y])%3) ans++;
				else if(px!=py) 
				{
					p[px]=py;
					d[px]=d[y]-d[x];
				}	
			}
			else{
				if(px==py&&(d[x]-d[y]-1)%3) ans++;
				else if(px!=py)
				{
					p[px]=py;
					d[px]=d[y]-d[x]+1;
				}
			}
			
		}
		
	} 
	printf("%d",ans);
	return 0;
}
原网站

版权声明
本文为[RCyyds]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qw991/article/details/124997091