Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20517 | Accepted: 6071 |
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.
Source
#include <iostream>
#include <stdio.h>
#define N 100001
using namespace std;
int f[N];
int g[N];
int rank[N];
int n;
void makeSet(){
for(int i = 1; i <= n; i++){
f[i] = i;
g[i] = 0;
rank[i] = 0;
}
}
int findRoot(int x){
if( f[x] == x ){
return x;
} else {
int temp = f[x]; //記錄當前的父節點
f[x] = findRoot(f[x]); //維護父節點,並壓縮路徑。
if(temp != f[x]) { //如果剛纔記錄的當前父節點不是根節點,則需要維護。
if(g[x] == 0){
g[x] = g[temp];
} else {
g[x] = (g[temp] + 1)%2;
}
}
return f[x];
}
}
void merge(int a,int b){
int ra = findRoot(a);
int rb = findRoot(b);
if(ra != rb){
if(rank[ra] < rank[rb]) {
f[ra] = rb;
g[ra] = ((g[a] + g[b]) + 1)%2; //合併時,因爲曾經的根節點,現在不是根節點了。
//需要維護它與現在根節點的關係。
} else {
f[rb] = ra;
g[rb] = ((g[a] + g[b]) + 1)%2;
if(rank[ra] == rank[rb]){
rank[ra]++;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int m;
scanf("%d%d",&n,&m);
makeSet();
char command;
int a;
int b;
for(int i = 0; i < m;i++){
getchar();
command = getchar();
scanf("%d%d",&a,&b);
if( command == 'A') {
int ra = findRoot(a);
int rb = findRoot(b);
if(ra != rb){
printf("Not sure yet.\n");
} else {
if(g[a] == g[b]){
printf("In the same gang.\n");
} else {
printf("In different gangs.\n");
}
}
} else {
merge(a,b);
}
}
}
return 0;
}