您的位置:首页 > 其它

poj 1182 食物链(DSU)

2016-03-07 08:58 330 查看
①普通并查集:

f[i]=i,表示i属于A

f[i]=i+n,表示i属于B

f[i]=i+2*n,表示i属于C

每次合并之前先进行判断

如果x和y属于同类,则需要判断(x,y+n)和(x,y+2*n)

如果x吃y,则需要判断(x,y)和(x+2*n,y)

②带权并查集:

每次合并压缩路径的时候, 模三取余,然后判断权值即可

附上普通并查集的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=50005;
int n,k;
int f[3*maxn];

void Make_Set(){
int Max=3*n;
for(int i=0;i<Max;i++){
f[i]=i;
}
}

int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}

void Union(int x,int y){
int rx=find(x);
int ry=find(y);
f[ry]=f[rx];
}

bool judge(int x,int y){
return find(x)==find(y);
}

int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
scanf("%d%d",&n,&k);
Make_Set();
int res=0;
int op,x,y;
while(k--){
scanf("%d%d%d",&op,&x,&y);
x--,y--;
if(x<0||x>=n||y<0||y>=n) {res++;continue;}
if(op==1){
if(judge(x,y+n)||judge(x,y+2*n))
res++;
else{
Union(x,y);
Union(x+n,y+n);
Union(x+2*n,y+2*n);
}
}
else{
if(judge(x,y)||judge(x,y+2*n))
res++;
else{
Union(x,y+n);
Union(x+n,y+2*n);
Union(x+2*n,y);
}
}
}
printf("%d\n",res);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: