您的位置:首页 > 其它

poj1182食物链(带权并查集)

2015-05-10 11:38 246 查看
///基本思路:带权并查集(简单的理解就是将有关系的点合并到一个集合,记录每个点到集合根节点的权重)

#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX 50010
using namespace std;
int par[MAX];///记录集合根节点
int offset[MAX];///记录每个节点到根节点的偏移量
int n,m;
void make_set()
{
for(int i=1; i<=n; ++i)
{
par[i]=i;
offset[i]=0;///相对于根的偏移量
}
}
int find_set(int x)
{
if(x!=par[x])
{
int tmp=find_set(par[x]);
offset[x]=(offset[par[x]]+offset[x])%3;///关键点1
par[x]=tmp;
}
return par[x];
}
void union_set(int x,int y,int v)
{
int tmp1=find_set(x);
int tmp2=find_set(y);
par[tmp2]=tmp1;
offset[tmp2]=(offset[x]-offset[y]+v+3)%3;///关键点2
}
int main()
{
scanf("%d%d",&n,&m);
make_set();
int d,a,b;
int ans=0;
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&d,&a,&b);
if(a>n||b>n)
{
ans++;
continue;
}
if(d==1)
{
if(find_set(a)==find_set(b))
if((offset[b]-offset[a]+3)%3!=0)
ans++;
else
union_set(a,b,0);
}
else if(d==2)
{
if(a==b)
{
ans++;
continue;
}
if(find_set(a)==find_set(b))
{
if((offset[b]-offset[a]+3)%3==1);
else
ans++;
}
else
union_set(a,b,1);
}
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: