poj 1703 Find them,Catch them
Description
Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:
1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.
2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.
Input
Output
Sample Input
1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4
Sample Output
Not sure yet. In different gangs. In the same gang.
#include <iostream>
#include <cstdio>
using namespace std;
int p[100010],rela[100010];
int T,N,M,a,b;
char flag;
void make()
{
for(int i=1;i<=N;i++)
{
p[i]=i;
rela[i]=0;
}
}
int find(int x)
{
int temp=p[x];
if(x==p[x])
return x;
p[x]=find(p[x]);
rela[x]=(rela[x]==rela[temp])?0:1; //等于0表示属于同一类
return p[x];
}
void unionSet(int x,int y,int px,int py)
{
p[px]=py;
rela[px]=(rela[x]==rela[y])?1:0; //x,y肯定是不在同一个帮派
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
make();
while(M--)
{
scanf("\n%c%d%d",&flag,&a,&b);
//cin>>flag>>a>>b;
int pa=find(a),pb=find(b);
if(flag=='A')
{
if(pa!=pb) //父亲不同,说明到此句还没有建立关系
{
cout<<"Not sure yet."<<endl;
continue;
}
if(rela[a]==rela[b]) //父亲相同,在比较两者和父亲的关系
{
cout<<"In the same gang."<<endl;
continue;
}
cout<<"In different gangs."<<endl;
continue;
}
if(flag=='D')
if(pa!=pb)
unionSet(a,b,pa,pb);
}
}
return 0;
}