Find them, Catch them
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 38608 | Accepted: 11887 |
Description
The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal belongs to. The present question is, given two criminals; do they belong to a same clan? You must give your judgment based on incomplete information. (Since the gangsters are always acting secretly.)
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.
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
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case begins with a line with two integers N and M, followed by M lines each containing one message as described above.
Output
For each message "A [a] [b]" in each case, your program should give the judgment based on the information got before. The answers might be one of "In the same gang.", "In different gangs." and "Not sure yet."
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.
题目大意:
这个城市有两股恶势力,一共有N个人,警察只知道这N个人中的部分的线索(线索是不完整的),线索只知道M条,要求通过线索,判断这两个人是否是属于同一股势力的。
遇到的问题和思路:
本来以为这道题目是简单的TAT,结果刚开始的思路错了,纠正了我好久。然后这道题的最难点就是在于,如果前面给你的所有的人之间都是有联系的,然后这些人可以通过树连在一起,但是,如果后来突然有一组数据给你两个人和前面的所有人毫无关系,那会怎么办(就在这里卡主了TAT)。
看了一下别人的题解,是用另外一个数组来联系着两个人。首先这两个人如果是敌对势力,那么就创定一个数组foe,然后让foe[a] = b, foe[b] = a,就说明这两个人是敌对关系,用这一组数组,既保存了敌对关系的数据,又为又来判断关系提供了一个依据。
给出AC代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX = 150000 + 5;
int n, m, a, b;
char ch;
int par[MAX], foe[MAX], rank[MAX];
void inti(){
for(int i = 0; i < MAX; i++){
par[i] = i;
foe[i] = 0;
rank[i] = 0;
}
return ;
}
int find(int a){
if(par[a] == a)return a;
else return par[a] = find(par[a]);
}
void unite(int x, int y){
x = find(x);
y = find(y);
if(x == y) return ;
if(rank[x] < rank[y]){
par[x] = y;
}
else {
par[y] = x;
if(rank[x] == rank[y]){
rank[x]++;
}
}
}
int same(int x, int y){
return find(x) == find(y);
}
void solve(){
scanf("%d%d", &n, &m);
getchar();
//if(n == 2 && m >= 1){printf("In different gangs.\n");return ;}
inti();
for(int i = 0; i < m; i++){
scanf("%c%d%d", &ch, &a, &b);
getchar();
if(ch == 'D'){
if(foe[a])unite(foe[a], b);
if(foe[b])unite(foe[b], a);
foe[b] = a;
foe[a] = b;
}
else {
if(same(a, foe[b])) printf("In different gangs.\n");
else if(same(a, b))printf("In the same gang.\n");
else printf("Not sure yet.\n");
}
}
return ;
}
int main(){
int t;
scanf("%d",&t);
getchar();
while(t--){
solve();
}
return 0;
}
给出测试数据:
/*
3
5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4//原题的
5 7
A 1 2
D 1 2
A 1 2
not sure yet.
D 2 4
A 1 4
in different gangs
D 3 5
A 1 5
not sure yet.
4 4
D 1 2
D 3 4
D 1 4
A 1 3
ans : In the same gang.
2 1
A 1 2
ans : In different gangs.或者是not sure yet 都能AC,例如我的AC代码注释掉的那句
*/