食物链,洛谷之提高历练地,并查集

本文介绍了一种利用并查集维护食物链中生物间关系的方法,通过三倍空间分配来记录生物的同类、食物及天敌,确保了数据的一致性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正文

      第二题:食物链

      这题经典啊!!!我们可以想象,如果我们可以搞一个并查集来维护x的同伙,天敌和食物就好了。

      我们想到了开三倍空间来维护x的天敌,同伙和食物。

      我们假设有一句话是x和y是同类,那么要满足两个条件,x不吃y,而且y不吃x。如果都满足,那么我们就可以把他们联系起来。

      我们再假设一句话是x吃y,那么要满足的条件显然有,x和y不为同类,而且y不吃x。

      我们再把他们联系起来即可。

      怎么联系呢?,我们看代码吧~

#include<cstdio>
#include<cstdlib>
#include<cstring>

int n,m;
int f[150010];//1<=i<=50000 1到50000表示i的同类,i+n表示i的食物,i+2*n为i的天敌。
int ans=0;

int findpa(int x){
	if(f[x]!=x) return f[x]=findpa(f[x]);
	return f[x];
}

bool comp(int x,int y){
	return findpa(x)==findpa(y);
}

void couple(int x,int y){
	if(findpa(x) != findpa(y)) f[findpa(x)]=findpa(y);
}

int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=3*n;i++)
		f[i]=i;
	for(int i=1;i<=m;i++){
		int k,x,y;
		scanf("%d %d %d",&k,&x,&y);
		if(k==2 && x==y || x>n || y>n){
			ans++;
			continue;	
		}
		if(k==1){
			if(comp(x,y+n) || comp(x+n,y)){//x不吃y,而且y不吃x。
				ans++;
				continue;
			}
			couple(x,y);
			couple(x+n,y+n);
			couple(x+2*n,y+2*n);
		}
		else{
			if(comp(x,y+n) || comp(x,y)){//x和y不为同类,而且y不吃x
				ans++;
				continue;			
			}
			couple(x,y+2*n);
			couple(x+n,y);
			couple(x+2*n,y+n);
		}
	}
	printf("%d\n",ans);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值