//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;
}
本文介绍了一道使用并查集算法解决的典型题目——POJ1182。通过分析题目背景及需求,详细解释了如何利用并查集来判断动物之间的食物链关系,并给出了具体实现代码。
457

被折叠的 条评论
为什么被折叠?



