这题很容易发现是并查集..但我就是MLE了好久才过...原来有个细节一直没注意到..
用father[]可以不断向上指直道指向集合的标志数...用另外一个数组s[]可以指向这个集合所相对的那个集合标志数..
在D x y 时判断合并x,y的集合时..一定要注意..
不仅 x=getfahter(x); y=getfather(y);
同样 s[x]=getfather(s[x]); s[y]=getfather(y)
我就是因为s[]没有做对~~就MLE了好久..我是用递归写的getfather..若使用迭代..没更新s[]会TLE....
#include<iostream>
#include<queue>
#include<stdio.h>
using namespace std;
int t,n,m,x,y,s[100005],father[100005];
char c;
int getfather(int x)
{
if (father[x]==x) return x;
return father[x]=getfather(father[x]);
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
for (x=1;x<=n;x++) father[x]=x;
memset(s,0,sizeof(s));
while (m--)
{
do
{
scanf("%c",&c);
}while (c!='A' && c!='D');
scanf("%d%d",&x,&y);
if (c=='A')
{
x=getfather(x);
y=getfather(y);
if (x==y) printf("In the same gang.\n");
else
if (getfather(s[x])==y) printf("In different gangs.\n");
else printf("Not sure yet.\n");
}else
{
x=getfather(x);
y=getfather(y);
if (!s[x]) s[x]=y;
if (!s[y]) s[y]=x;
s[x]=getfather(s[x]);
s[y]=getfather(s[y]);
if (s[x]!=y) father[s[x]]=y;
if (s[y]!=x) father[s[y]]=x;
}
}
}
return 0;
}