POJ 1703 種類並查集
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.
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.
題目大意:有兩個幫會,然後輸入格式為D a b 表示ab兩個人不是一個幫派,輸入格式為A a b是讓輸入ab兩個人是不是一個幫會的,是就輸出In the ……,不是的話就是輸出In different ……,如果單憑當前的相對關係不能夠判斷兩人的所在幫派,那就輸出Not sure ……
並查集可以將兩個有同一種關係的元素歸併到一個集合當中,這道題目不好處理的就是每次輸入的關係正好與並查集的處理相反,可以這樣來處理:
給出ab,那麼ab肯定是兩個幫派裡的,假設存在兩個幫會AB,因此a有可能是A,也有可能是B幫會,那就需要將這兩種情況全部都考慮進去,規定(a+n,b)表示a屬於B幫派,b屬於A幫派,(a,b+n)表示a屬於A幫派,b屬於B幫派,那麼開始預處理就要由1--n,處理到1--2*n,這樣就能將兩種情況全部考慮進去,剩下的就是並查集的板子
#include <iostream>
#include <algorithm>
#include <queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define init(i,a) memset(i,a,sizeof i)
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1e5+10;
int f[N<<1];
bool vis[N];
int Findf(int v){
return f[v]==v?v:f[v]=Findf(f[v]);
}
void Merge(int x,int y){
int t1=Findf(x);
int t2=Findf(y);
if(t1!=t2){
f[t2]=t1;
}
return ;
}
bool Same(int x,int y)
{
return Findf(x)==Findf(y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int T;
scanf("%d",&T);
int n,m;
while(T--){
init(vis,0);init(f,0);
scanf("%d%d\n",&n,&m);
rep(i,1,2*n) f[i]=i;
char ch;int x,y;
rep(i,1,m){
scanf("%c %d %d\n",&ch,&x,&y);
if(ch=='A'){
if(Same(x,y)) printf("In the same gang.\n");
else if(Same(x+n,y)||Same(x,y+n)) printf("In different gangs.\n");
else {printf("Not sure yet.\n");continue;}
}else{
Merge(x+n,y);
Merge(x,y+n);
}
}
}
return 0;
}