POJ 1703 Find them, Catch them
题意
塔都市的警察局决定治理混乱,从城市中的两个帮派开始行动,Gang Dragon和Gang Snake。但是,警方首先需要确定犯罪分子属于哪个团伙。目前的问题是,两名罪犯,他们属于同一个帮派吗?您必须根据不完整的信息做出判断。(因为歹徒总是暗中行动。)
假设\(N(N<= 10^5)\)罪犯目前在塔都市,编号从1到N。当然,他们中至少有一人属于Gang Dragon,同样至少有一人属于Gang Snake。将按顺序给出\(M(M<= 10^5)\)个消息,它们分为以下两种:
- D [a][b]
其中[a]和[b]是两个罪犯的编号,以及他们属于不同的帮派。 - A [a] [b]
其中[a]和[b]是两个罪犯的编号。这需要您回答a和b是否属于同一个帮派。
对于每种情况下的每条消息“A [a][b]”,您的程序应根据之前获得的信息进行判断。答案可能是“在同一帮派中”,“在不同的帮派中”和“还不确定”。
思路
不同集合查询方法:
- (Find(y+n) == Find(x) || Find(x+n) == Find(y)) 不同集合
- (Find(x) == Find(y) || Find(x+n) == Find(y+n)) 相同集合
- 不确定是否同一集合
const int N=1e5+10;
int p[N<<1];
int n,m;
int find(int x)
{
if(x != p[x]) p[x]=find(p[x]);
return p[x];
}
void merge(int a,int b)
{
int pa=find(a);
int pb=find(b);
if(pa != pb) p[pa]=pb;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n*2;i++) p[i]=i;
while(m--)
{
char op[2];
int a,b;
scanf("%s%d%d",op,&a,&b);
if(op[0] == 'D')
{
merge(a,b+n);
merge(a+n,b);
}
else
{
if(find(a) == find(b))
puts("In the same gang.");
else if(find(a) == find(b+n))
puts("In different gangs.");
else
puts("Not sure yet.");
}
}
}
//system("pause");
return 0;
}