POJ 1182 食物链

是一道挺不错的并查集题目。不同于普通并查集的题,这道题不仅仅需要对一种情况进行分集合,而是对三种情况区分集合:两种动物同类,A吃B,B吃A。这样我们可以把数组开大三倍,a[i]表示第i个动物属于第1类动物这种情况,a[i+n]表示第i个动物属于第2类动物这种情况,a[i+2*n]表示第I个动物属于第3类动物这种情况。

当输入查询时,如果判断是正确的,就把可能发生的几种情况都放进同一个集合里面。例如,加入x和y是同类动物这个查询没有错误,那就把a[x]和a[y]、a[x+n]和a[y+n]、a[x+2*n]和a[y+2*n]分别放进同一个集合里。判断不正确就从反面进行查找。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<list>
#include<string>
#include<map>
using namespace std;
#define maxn 50050
int father[maxn*3];
int find(int n)
{
	if(n!=father[n]) father[n]=find(father[n]);
	return father[n];
}
int main()
{
	int n,k;
	int sum=0;
	int kind,x,y;
	scanf("%d%d",&n,&k);
	for(int i=0;i<=3*n;i++)
	{
		father[i]=i;
	}
	while(k--)
	{
		scanf("%d%d%d",&kind,&x,&y);
		if(x>n||x<=0||y>n||y<=0)
		{
			sum++;
			continue;
		}
		if(kind==1)
		{
			if(find(x)==find(y+n)||find(x)==find(y+2*n))
				sum++;
			else 
			{
				father[find(x)]=find(y);
				father[find(x+n)]=find(y+n);
				father[find(x+2*n)]=find(y+2*n);
			}
		}
		else if(kind==2)
		{
			if(find(x)==find(y)||find(x)==find(y+2*n)||find(x+2*n)==find(y+n))
				sum++;
			else 
			{
				father[find(x)]=find(y+n);
				father[find(x+n)]=find(y+2*n);
				father[find(x+2*n)]=find(y);
			}
		}
	}
	printf("%d\n",sum);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值