poj1182 食物链 (并查集)

//poj1182 并查集 <wbr></wbr>
//题目意思:有三种动物A,B,C。A吃B,B吃C,c吃A。给出一系列说法,判断错误个数。

//小菜在这道并查集入门题卡了很久啊,终于下定决心把它啃掉。
//原来要记录一下当前动物与根的关系。在给出的两种动物中的根不相同时要进行树的合并。
//若两动物根相同可以根据它们与根的关系去判断。

//代码如下:

#include<iostream>
#include<cstdio>


using namespace std;


int path[50002],relation[50002];
void makeset ( int x)
{
	relation [x] = 0;
	path[x ] = x;
}
int findset ( int x)
{
	if(x!=path[x])
	{
		int temp=path[x];
		path[x]=findset(path[x]);//这里依然用递归并压缩路径
		relation[x]=(relation[x]+relation[temp])%3;//根结点变了嘛,要更新一下关系,这个步骤很关键
	}
	return path[x];
}
void unionset ( int px,int py,int d)
{
	path[px]=py;//把根py当作px的根
	relation[px]=d;
}


int main()
{
	int n,cas;
	
	
	scanf("%d%d",&n,&cas);//这里不用while,不然就wa,我就wa了n次
	
	
	int cnt=0;
	int i,j;
	for(i=1;i<=n;i++)
		makeset(i);
	for(j=0;j<cas;j++)
	{
		int d,x,y;
		scanf("%d%d%d",&d,&x,&y);
		if(x>n||y>n)
		{cnt++;
		continue;
		}
		if(d==2&&x==y)
		{
			cnt++;
			continue;
		}
		int px=findset(x),
			py=findset(y);
		if(px!=py)//还没联系,“并”操作
		{
			unionset(px,py,(relation[y]-relation[x]+2+d)%3);
			//这里为什么是 relation[y]-relation[x]+2+d 呢,这就要找一下规律了
			//这里relation[x]==0时,表示x与根同类,等于1时表示 x吃根,2就是 根吃x;
		}
		else 
		{
			if(d==1)
			{
				if(relation[x]!=relation[y])//表示不是同类
					cnt++;
			}
			else
			{
				if(relation[x]!=(relation[y]+1)%3)//表示x吃不了y
					cnt++;
			}
		}
	}
	printf("%d\n",cnt);
	return 0;
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值