功夫不负有心人,改了一天,总算AC。
并查集用来表示等价类,这里的等价类是什么?是“关系可以确定”。如果A和B的关系可以确定,B和C的关系可以确定,则A,B,C之间的关系都能确定,所以该关系有传递性。等价关系其他的两个性质也都满足。在此基础上,我们又引进一个数组表示关系到底是怎样的,并在查找和压缩路径的过程中更新。
/*
* poj- Find them, Catch them
* mike-w
* 2011-10-26
* ---------------------------
* url: http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1003&ojid=1&cid=790&hide=0
* ---------------------------
* 并查集
* ---------------------------
* 改了一天,总算AC了!!!
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 100100
long set[SIZE],rec[SIZE],st[SIZE];
long N,M,T;
int init(long size)
{
long i;
for(i=0;i<=size;i++)
set[i]=-1,rec[i]=0;
return 0;
}
#ifndef recursive_find
long find(long e)
{
long top=0,node=e,root;
while(set[node]>0)
{
st[top++]=node;
node=set[node];
}
root=node;
while(top--)
{
node=st[top];
rec[node]=(rec[node]+rec[set[node]])&0x1;
set[node]=root;
}
return root;
}
#endif
#ifdef recursive_find
long find(long e)
{
if(set[e]<0) return e;
long node=set[e];
set[e]=find(set[e]);
rec[e]=(rec[e]+rec[node])&0x1;
return set[e];
}
#endif
long merge(long e1,long e2)
{
long r1=find(e1);
long r2=find(e2);
if(r1==r2) return 0;
long flag=!((rec[e1]+rec[e2])&0x1);
if(set[r1]>set[r2]) /* attach r1 to r2 */
rec[r1]=flag,set[r1]=r2;
else if(set[r1]<set[r2]) /* attach r2 to r1 */
rec[r2]=flag,set[r2]=r1;
else
rec[r1]=flag,set[r1]=r2,set[r2]--;
return 1;
}
int main(void)
{
long i,t1,t2,r1,r2;
char buf[10];
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
scanf("%ld",&T);
while(T-->0)
{
scanf("%ld%ld",&N,&M);
init(N);
for(i=0;i<M;i++)
{
scanf("%s%ld%ld",buf,&t1,&t2);
if(buf[0]=='D')
merge(t1,t2);
else
{
r1=find(t1);
r2=find(t2);
if(r1!=r2)
puts("Not sure yet.");
else
{
if(rec[t1]==rec[t2])
puts("In the same gang.");
else
puts("In different gangs.");
}
}
}
}
return 0;
}