0
点赞
收藏
分享

微信扫一扫

POJ--1703并查集(区分两个集合)

POJ--1703并查集(区分两个集合)_ios

 

     

POJ--1703并查集(区分两个集合)_并查集_02

 

 

题意:输入n,m。n个人,m个规定/询问。一共有两个集合,A:询问a,b是否在同一个集合?D:表明a,b不在同一个集合。输出有三种,不在同一集合,在同一集合,不确定。

    解析:其实有点离散化的意思。传统并查集是合并两个集合,而这个题是分开两个集合。那么可以这么做,想办法进行合并操作。输入a,b,a,b没有了关系,但是可以规定,a+n,b属同一集合,a,b+n属于同一集合。即,n右边a+n的那些和b放入同一集合,n右边b+n的那些和a放入同一集合,这样a,b就撇开了关系。就可以进行join()操作了。判断过程具体看代码吧。输入注意一下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=2e5+1000;
int pr[maxn];
//int vis[maxn];
int sum=0;
int n,m;
int find(int x){
while(x!=pr[x])
{
pr[x]=pr[pr[x]];
x=pr[x];
}
return x;
}
void join(int x1,int x2)
{
int f1=find(x1),f2=find(x2);
if(f1!=f2)
{
pr[f1]=f2;
}
return ;
}
void first()
{
for(int i=0;i<=n*2+10;i++)
{
pr[i]=i;
}
}
bool check(int a,int b)
{
int f1=find(a),f2=find(b);
// cout<<f1<<"-"<<f2<<endl;
if(f1==f2)
{
return true;
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
first();
char ch,ch2;
while(m--)
{

// cin>>ch;
int x,y;
scanf("%c",&ch);
scanf("%c%d%d",&ch,&x,&y);
if(ch=='D')
{
join(x+n,y);
join(x,y+n);
}
else
{
if(check(x,y)||check(x+n,y+n))  //如果x+n,x+n属于同一个集合,那么a,b之前肯定记录过而且同属一个集合。
cout<<"In the same gang."<<endl;  
else if(check(x+n,y)||check(y+n,x))  //如果x+n和y同属一个集合或者y+n和x同属一个集合,那么x,y肯定同属一个集合了。
cout<<"In different gangs."<<endl;
else                   
cout<<"Not sure yet."<<endl;  //否则就不确定
}
}
}
}

  



举报

相关推荐

0 条评论