题意:
有两个帮派龙帮,蛇帮,警察需要验证嫌疑人属于哪个帮派。需要解决的问题是,给出两个嫌疑人,你必须通过不完全的信息,判断他们是否属于一样帮派。
有 N ( 1 < N < 100000 ) 个嫌疑人,标号 1 到 N,至少有一个属于龙帮,一个属于蛇帮。有 M ( 1 < M < 100000 ) 条信息,有两种类型的信息,
1.D a b 意味着 a 和 b 属于不同帮派
2.A a b 查询 a 和 b 是否属于一个帮派
输入:
第一行测试次数,第二行两个整数,N,M 意味着有 N 个嫌疑人和 M 条信息
接下来的M行输入信息
输出:
对于每个 A a b 的输出,有三种可能,“不能确定”,“不在一个帮派”,“在一个帮派”,输出一种。
比如输入:
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
比如输出:
Not sure yet.
In different gangs.
In the same gang.
思路:
并查集,代码很清楚。
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
#define MAX_SIZE 100010
#define UNKOWN -1
int others[MAX_SIZE]; // 非该嫌疑人本人的帮派(干脆叫该嫌疑人的敌对帮派吧)
int parents[MAX_SIZE];
int find_gang( int suspect ){
if( suspect != parents[suspect] )
parents[suspect] = find_gang( parents[suspect] );
return parents[suspect];
}
// 简单的合并了下
void merge_gang( int suspect_a, int suspect_b ){
int gang_of_a = find_gang( suspect_a );
int gang_of_b = find_gang( suspect_b );
parents[gang_of_a] = gang_of_b;
}
// 将两个嫌疑人分配到不同的帮派里面
void differ( int suspect_a, int suspect_b ){
// 若是 a 的敌对帮派未知,那么僵敌对帮派设为 b
if( others[suspect_a] == UNKOWN ){
others[suspect_a] = suspect_b;
}
else{
// a 的敌对帮派已知,那么就将 b 与 a 的敌对帮派归为一类
merge_gang( others[suspect_a], suspect_b );
}
// 若是 b 的敌对帮派未知,那么僵敌对帮派设为 a
if( others[suspect_b] == UNKOWN ){
others[suspect_b] = suspect_a;
}
else{
// b 的敌对帮派已知,那么就将 a 与 b 的敌对帮派归为一类
merge_gang( others[suspect_b], suspect_a );
}
}
void answer( int suspect_a, int suspect_b ){
if( others[suspect_a] == UNKOWN || others[suspect_b] == UNKOWN ){
cout << "Not sure yet.\n";
return;
}
int gang_of_a = find_gang( suspect_a );
int gang_of_b = find_gang( suspect_b );
int other_gang_of_a = find_gang( others[suspect_a] );
int other_gang_of_b = find_gang( others[suspect_b] );
if( gang_of_a == gang_of_b ){
cout << "In the same gang.\n";
return;
}
// 若是 a 的帮派和 b 的敌对帮派一致,证明 a,b 不在一个帮派
if( gang_of_a == other_gang_of_b ){
cout << "In different gangs.\n";
return;
}
cout << "Not sure yet.\n";
}
int main(){
int test_num;
scanf( "%d", &test_num );
while( test_num-- ){
memset( others, UNKOWN, sizeof( others ) );
int suspect_num, msg_num;
scanf( "%d%d", &suspect_num, &msg_num );
for( int i = 0; i <= suspect_num; ++i )
parents[i] = i;
while( msg_num-- ){
char ch;
int suspect_a;
int suspect_b;
scanf("\n%c%d%d", &ch, &suspect_a, &suspect_b);
if( ch == 'D' ){
differ( suspect_a, suspect_b );
}
else{
answer( suspect_a, suspect_b );
}
}
}
return 0;
}