您的位置:首页 > 其它

[poj1703]Find them, Catch them(种类并查集)

2017-12-01 23:05 417 查看

题意:食物链的弱化版本

解题关键:种类并查集,注意向量的合成。

$rank$为1代表与父亲对立,$rank$为0代表与父亲同类。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
#define M 100005
int fa[M],rank1[M];
int find1(int x){
if(x==fa[x]) return x;
int tmp=fa[x];
fa[x]=find1(tmp);
rank1[x]=(rank1[x]+rank1[tmp])%2;
return fa[x];
}
void unite(int x,int y){
int t=find1(x);
int t1=find1(y);
if(t!=t1){//合并的时候需要用到向量的合成和差
fa[t1]=t;
rank1[t1]=(1-rank1[y]+rank1[x])%2;
}
}
char ch[10];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
fa[i]=i;
rank1[i]=0;
}
for(int i=0;i<m;i++){
int tmp,tmp1;
scanf("%s%d%d",ch,&tmp,&tmp1);
if(ch[0]=='D') unite(tmp,tmp1);
else{
int x=find1(tmp);
int y=find1(tmp1);
if(x==y){//可以判断出关系
int r=(2-rank1[tmp]+rank1[tmp1])%2;
if(r==0) printf("In the same gang.\n");
else printf("In different gangs.\n");
}
else printf("Not sure yet.\n");
}
}
}
return 0;
}

 法二:$fa$数组代表$i$属于$A$或$i$属于$B$

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn=100005;
int fa[maxn*2];
int find1(int x){
int r=x;
while(r!=fa[r])  r=fa[r];
int i=x,j;
while(i!=r){
j=fa[i];
fa[i]=r;
i=j;
}
return r;
}

void unite(int x,int y){
x=find1(x),y=find1(y);
if(x!=y) fa[x]=y;
}

int main(){
int T;
scanf("%d",&T);
while(T--){
int N,M,x,y;
char opt[10];
scanf("%d%d",&N,&M);
for(int i=0;i<=2*N;i++) fa[i]=i;
while(M--){
scanf("%s%d%d",opt,&x,&y);
if(opt[0]=='A'){
if(find1(x)==find1(y)) printf("In the same gang.\n");
else if(find1(x)==find1(y+N)&&find1(x+N)==find1(y)) printf("In different gangs.\n");
else printf("Not sure yet.\n");
}
else{
unite(x,y+N);
unite(x+N,y);
}
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: