poj 1182 食物链

本文介绍了一道关于食物链的经典并查集题目,详细解释了如何利用并查集来判断动物之间的关系是否合理,并提供了完整的代码实现。

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

  食物链是一道经典的并查集的题目,蕴含了并查集最基本的查询与合并的方法。

首先,这是个中文题,题意自己理解。

从题意中可以了解到,要判断是不是假话有三种方法,第二、三种显而易见,一个if就可以解决问题。第一种就要用到并查集了(出现在前面的都是真话(还未有冲突),后面的与前面的有冲突就是假话)。

首先,什么是并查集呢,一个可以在O(1)时间内查询两者在不在一个集合内,或者合并两个集合。

根据这一道题,应该维护三个域(集合),就是一个动物的吃域,被吃域,和同类域。

(用并查集查询他们的所在域)如果x和y是同类(d==1)那么x的吃域和y的被吃域显然不能重合,如果不是同类,那么x的被吃域和y吃域显然不能重合(当然他们不能是同类),判定完了后,要将正确的域合并(并查集合并)。

(假话别忘了合并真的)

下面是代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int ma=50010;
int fa[3*ma],chi[ma],beichi[ma],tong[ma];//维护的域
int n,k;
int find(int x)//查询
{
	if(fa[x]==x)
	return x;
	return fa[x]=find(fa[x]);
}
void get(int x,int y)
{
	fa[find(x)]=find(y);//合并两个域 
}
int ans;
int main()
{
	cin>>n>>k;
	for(int i=0;i<3*ma;i++)
	{
		fa[i]=i;
	}
	for(int i=0;i<ma;i++)
	{
		tong[i]=i;
		chi[i]=i+ma;
		beichi[i]=i+ma+ma;
	}
	for(int i=1;i<=k;i++)
	{
		int d,x,y;
		scanf("%d%d%d",&d,&x,&y);
		if((x==y&&d==2)||x>n||y>n)
		{
			ans++;
			continue;
		}
		else//记住要先判定再合并,如果是假话就直接跳过了。
		{
			if(d==1)
			{
				if(find(beichi[x])==find(chi[y])||find(beichi[y])==find(chi[x]))//如果是同类的判定
				{
					ans++;
					continue;
				}
				get(beichi[x],beichi[y]);//将正确的域合并
				get(chi[x],chi[y]);
				get(tong[x],tong[y]);
			}
			else
			{
				if(find(tong[x])==find(tong[y])||find(chi[y])==find(tong[x]))//如果是吃与被吃的关系的判定
				{
					ans++;
					continue;
				}			
				get(chi[x],tong[y]);//将正确的域合并
				get(tong[x],beichi[y]);
				get(beichi[x],chi[y]);
			}
		}
		
	}
	printf("%d\n",ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值