POJ 1703 Find them, Catch them (關係並查集)

畫船聽雨發表於2014-02-28

這道題目的描述我感覺還是抄嘯爺的吧,這個描述太逗了啊。

題意:某城市存在蛇幫和龍幫兩大幫派(話說名字還能再挫一點點嗎. . . )。在某一次像東莞這樣的大規模的掃黃打非中,警察抓住了 n 個人,但是不缺定他們分別屬於哪個幫派。現在給你一些條件,然後讓你判斷兩個人是否屬於同一個幫派。

這是一道關係並查集的題目啊,第一次做。嘯爺很耐心的講解了思路。過程很好理解啊。

就是這個並查集需要儲存一下他自己與父親節點的關係,0代表不是一夥,1代表是一夥的。然後在向跟回溯的時候找到這個節點和父親節點的關係,如果相同r就 不改變,否則就改變。一直找到根節點判斷節點和根節點的關係。比較一下就知道是否是一個幫派了啊。因為除了0,就是1。

嘯爺的解釋:

關係並查集的合併:

當不屬於同一棵樹的兩個點 u , v確定關係時,要將兩棵樹進行合併。

仍以此題為例:

設ru,rv分別為u,v的跟節點,wu,wv分別表示u,v與跟節點的關係,w[]為節點與父節點的關係。

當wu == wv時,則表示ru和rv屬於不同幫派(因為此題中,每次確定關係均為不屬於同一幫派), 則w[ru] = 1,fa[ru] = rv;

當wu != wv時,則表示ru和rv屬於同一幫派 , 則w[ru] = 0,fa[ru] = rv;


Find them, Catch them
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 27932   Accepted: 8521

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. 

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


#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 10001000
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const int maxn = 101000;

using namespace std;

int f[maxn];
int w[maxn];
int r;


int _find(int x)
{
    int t = x;
    r = 0;
    while(x != f[x])
    {
        if(w[x])
        {
            if(r == 1)
                r = 0;
            else
                r = 1;
        }
        x = f[x];
    }
    f[t] = x;
    w[t] = r;
    return x;
}


int main()
{
    int t;
    cin >>t;
    int n, m;
    while(t--)
    {
       scanf("%d %d",&n,&m);
        char str;
        for(int i = 0; i <= n; i++)
        {
            f[i] = i;
            w[i] = 0;
        }
        while(m--)
        {
            scanf("%*c%c",&str);
            int x, y;
            if(str == 'A')
            {
                scanf("%d %d",&x, &y);
                int xx = _find(x);
                int r1 = r;
                int yy = _find(y);
                int r2 = r;
                if(xx != yy)
                   printf("Not sure yet.\n");
                else
                {
                    if(r1 == r2)
                       printf("In the same gang.\n");
                    else
                        printf("In different gangs.\n");
                }

            }
            else
            {
                scanf("%d %d",&x, &y);
                int xx = _find(x);
                int r1 = r;

                int yy = _find(y);
                int r2 = r;
                f[xx] = yy;

                if(r1 == r2)
                    w[xx] = 1;
                else
                    w[xx] = 0;
            }
        }
    }
    return 0;
}


相關文章