维护两个并查集 f1与f2

题目中所给两点间的关系都是对立的 而一共只有两个阵营 因此可以得出 a敌对b且b敌对c 则a与c为同伙

对于两点间关系的询问 首先要看两点之间的敌友关系是否已经确定 如果以敌对关系为边建立子图 则图中相邻两点为敌 间隔一点为友 以此类推 因此只要两点连通即可确定关系 可通过并查集f1实现

其次要看是敌还是友 可通过标记数组实现 比如新增a敌对b 如果之前还有a敌对c那就把b与c放入友好并查集f2 敌友关系即可明了

 

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;

struct node
{
int id;
int sta;
};

node book[100010];
int f1[100010],f2[100010];
int n,m;

void unite(int u,int v,int* f);
int getf(int p,int* f);

int main()
{
int t,i,j,u,v,fu,fv;
char ch[2];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(book,0,sizeof(book));
for(i=1;i<=n;i++)
{
f1[i]=i;
f2[i]=i;
}
for(i=1;i<=m;i++)
{
scanf("%s%d%d",ch,&u,&v);
if(ch[0]=='D')
{
unite(u,v,f1);
if(book[u].sta==1)
{
unite(book[u].id,v,f2);
}
else
{
book[u].id=v;
book[u].sta=1;
}
if(book[v].sta==1)
{
unite(book[v].id,u,f2);
}
else
{
book[v].id=u;
book[v].sta=1;
}
}
else
{
fu=getf(u,f1);
fv=getf(v,f1);
if(fu!=fv)
{
printf("Not sure yet.\n");
}
else
{
fu=getf(u,f2);
fv=getf(v,f2);
if(fu!=fv)
{
printf("In different gangs.\n");
}
else
{
printf("In the same gang.\n");
}
}
}
}
}
return 0;
}

void unite(int u,int v,int* f)
{
int fu,fv;
fu=getf(u,f);
fv=getf(v,f);
if(fu!=fv)
{
f[fv]=fu;
}
return;
}

int getf(int p,int* f)
{
if(f[p]==p) return p;
else
{
f[p]=getf(f[p],f);
return f[p];
}
}

 

用种类并查集的话就是个裸题了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;

int f[maxn],dis[maxn];
int n,q;

int getf(int p)
{
int res;
if(f[p]==p) return p;
res=getf(f[p]);
dis[p]=(dis[f[p]]+dis[p])%2;
f[p]=res;
return res;
}

void unite(int u,int v)
{
int fu,fv;
fu=getf(u),fv=getf(v);
if(fu!=fv){
f[fv]=fu;
dis[fv]=(dis[u]+dis[v]+1)%2;
}
}

int solve(int u,int v)
{
int fu,fv;
fu=getf(u),fv=getf(v);
if(fu!=fv){
return 0;
}
else{
if(dis[u]==dis[v]) return 1;
else return 2;
}
}

int main()
{
int t,u,v,res,i;
char op[10];
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++){
f[i]=i,dis[i]=0;
}
while(q--){
scanf("%s%d%d",op,&u,&v);
if(op[0]=='A'){
res=solve(u,v);
if(res==0) printf("Not sure yet.\n");
else if(res==1) printf("In the same gang.\n");
else printf("In different gangs.\n");
}
else{
unite(u,v);
}
}
}
return 0;
}