如题:http://poj.org/problem?id=1703
题目要求:N个罪犯,M组数据,D x y 表示便哈x y的2个人不是一个团伙 ,A x y表示不提问x y是不是一个团伙,输出Not sure yet .In different gangs .In the same gang.中的一个,1个A x y对应一个输出、
将能确定关系的罪犯并入一个集合,不管他们是不是一个团伙的,集合只代表他们之间能确定关系,用r【i】代表i罪犯和它所在的集合根p【i】是否是一个团伙,0表示相同,1
表示不同。
#include<iostream>
using namespace std;
#define N1 100005
int rela[N1];
int p[N1];
void make()
{
for(int i=1;i<N1;i++)
{
rela[i]=0;
p[i]=i;
}
}
int find(int x)
{
int temp=p[x];
if(p[x]==x)
return x;
p[x]=find(p[x]);
rela[x]=(rela[x]==rela[temp])?0:1;
return p[x];
}
void Union(int x,int y,int px,int py)
{
p[px]=py; //将x的根并入y集合
rela[px]=(rela[x]==rela[y])?1:0; //调整px和py的关系 提示:只有x y确定是不同的团伙,并且x还没并入y集合,才会进入这个函数.
}
int main()
{
int T,N,M,a,b;
char flag;
scanf("%d",&T);
getchar();
while(T--)
{
make();
scanf("%d %d",&N,&M);
getchar();
while(M--)
{
scanf("%c %d %d",&flag,&a,&b);
getchar();
int pa=find(a),pb=find(b);
if(flag=='A')
{
if(pa!=pb)
{
printf("Not sure yet.\n");
continue;
}
if(rela[a]!=rela[b])
{
printf("In different gangs.\n");//a,b在一个集合,代表关系已知,又因为a,b与父节点的关系不等,代表不在一个集合中
continue;
}
printf("In the same gang.\n");
continue;
}
if(flag=='D')
{
if(pa!=pb)
Union(a,b,pa,pb);
}
}
}
}