现在的位置: 首页 > 综合 > 正文

POJ 1182 食物链

2018年01月14日 ⁄ 综合 ⁄ 共 1076字 ⁄ 字号 评论关闭

是一道挺不错的并查集题目。不同于普通并查集的题,这道题不仅仅需要对一种情况进行分集合,而是对三种情况区分集合:两种动物同类,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;
}

抱歉!评论已关闭.