题目链接Find them, Catch them
题意:
刚开始看起来挺简单,但是我越看越觉得绕。。
- D [a] [b]
其中[a]和[b]是两个犯罪分子的编号,他们属于不同的帮派; - A [a] [b]
其中[a]和[b]是两个犯罪分子的编号,您要确定a和b是否属于同一帮派。
但是这里要清楚只有两个成员所属帮派都互为对立时,才能说属于两个不同帮派
这里因为有对立帮派的原因,我们做一个映射,我们规定a + n 为a 成员所属帮派的对立帮派
在D操作时,要注意,对于输入的ab 我们要把a和b的对立帮派进行合并的同时也要把b和a的对立帮派合并,因为a,b这里已经知道了互为对立的不同帮派
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 +5;
int f[2 * maxn];
void init(int n)
{
for(int i = 1; i <= 2 * n; i++){
f[i] = i;
}
}
int Find(int root)
{
int son = root;
while(root != f[root]){
root = f[root];
}
//压缩路径
while(son != root){
int temp = f[son];
f[son] = root;
son = temp;
}
return root;
}
void add(int x,int y)
{
int a = Find(x);
int b = Find(y);
if(a != b){
f[a] = b;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
cin>>n>>m;
init(n);
char s[2];
int a,b;
for(int i = 0; i < m; i++){
scanf("%s%d%d",s,&a,&b);
if(s[0] == 'A'){
int u = Find(a);
int v = Find(b);
if(Find(a) == Find(b + n)&&Find(b) == Find(a + n)){
printf("In different gangs.\n");
}
else if(u == v){
printf("In the same gang.\n");
}
else{
printf("Not sure yet.\n");
}
}
if(s[0] == 'D'){
add(a,b + n);//b +n 表示将a添加到b的对立帮派,下同
add(b,a + n);
}
}
}
return 0;
}