裸的带圈并查集
更新祖先的时候 顺便 维护一下 距离就可以了,距离只有0.1,分别代表两个帮派
合并的时候,更新距离
/* x->fx
y->fy
dis(fx->fy)=dis(x->fx)+dis(y->fy )+dis(x->y)
对应了 path[fx]=(path[x]+path[y]+ 1)%2;
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int fa[100005];
int path[100005]; //记录自己到祖先的距离
int find(int x) //找到祖先,并更新自己到祖先的距离
{
if (x==fa[x])
return x;
else
{
int fx=find(fa[x]);
path[x]=(path[x]+path[fa[x]])%2; //维护与祖先的关系
return fa[x]=fx;
}
}
int vis[100005];
int main()
{
int n,m;
int t,i,x,y;
char op;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);getchar();
for (i=1;i<=n;i++)
fa[i]=i,vis[i]=0,path[i]=0;
for (i=1;i<=m;i++)
{
scanf("%c %d %d",&op,&x,&y);
getchar();
int fx=find(x);
int fy=find(y);
if (op=='D')
{
if (fx!=fy)
{
fa[fx]=fy;
path[fx]=(path[y]+path[x]+ 1)%2;
// path[fx]=( path[x]+ 1)%2; 煞笔了,之前写成这个了
/* x->fx
y->fy
dis(fx->fy)=dis(x->fx)+dis(y->fy )+dis(x->y)
对应了 path[fx]=(path[x]+path[y]+ 1)%2;
*/
}
}
else
{
if (fx==fy)
{
if (path[x]==path[y] )
printf("In the same gang.\n");
else
printf("In different gangs.\n");
}
else
printf("Not sure yet.\n");
}
}
}
return 0;
}