POJ 1703

    一道很好的題目,和POJ食物鏈那題解法一樣,雖然AC了其實還是不能深入瞭解其本質,只能在這裏談一談表象。
    通過讀題我們可以發現可以從兩組信息中推斷出新的信息,例如:輸入中有D 1 2D 2 3,我們可以得知1和3是同一組的。因此我們需要一種數據結構能夠維護給出的關係,並且幫助我們保存推斷出的關係。如果我是第一次聽到這個需求,我肯定認爲這種數據結構不存在,或者至少實現起來很複雜,不過其實有一種很簡單的數據結構就可以做到,那就是——並查集。個人覺得很難理解爲什麼並查集能夠做到這些,可是事實的確如此。
    要做到這個,首先我們要對標號進行一個小處理,即假設1屬於A組(代指題目中的Gang Dragon),那麼標號不變,如果1屬於B組( Gang Snake),那麼標號加上n。要注意,對於題目給出的編號來說,我們既可以將其歸爲A組,也可以將其歸爲B組,所以我們兩個假設都處理。如果題目給出D 1 2,那麼我們就將1和2+n合併爲一個集合,然後再將1+n和2合併爲另一個集合,對於D 2 3同樣,此時一個集合爲(1, 2+n, 3),另一個集合爲(1+n, 2, 3+n),我們可以發現題目中給出的關係和推斷出的關係都保存下來了。
    對於A 1 3來說,由於上述兩個集合是等價的,所以可以簡單假設1屬於A組, 3屬於B組或1屬於A組, 3屬於A組來判斷,而不需要反過來再檢查一遍。
    那也許有人會認爲假設1屬於A組,2屬於B組不就好了嗎?但是如果遇到如下輸入,你的假設就可能導致錯誤結果:

D 1 2
D 2 3
D 4 5
D 5 6
A 3 4

代碼(G++):

#include <iostream>
#include <cstdio>
#include <cstring>

#define MAXN 100000
using namespace std;

int pre[MAXN*2+5];

int find(int a)
{
    if(pre[a] != a) pre[a] = find(pre[a]);
    return pre[a];
}

void unite(int a, int b)
{
    int pa, pb;
    pa = find(a);
    pb = find(b);
    if(pa != pb) pre[pa] = pb;
}

bool same(int a, int b)
{
    int pa, pb;
    pa = find(a);
    pb = find(b);
    if(pa == pb) return true;
    else return false;
}

int main()
{
    int t, n, m, a, b;
    char ch;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d %d", &n, &m);
        for(int i=1; i<=n*2; i++) pre[i] = i;
        for(int i=0; i<m; i++)
        {
            scanf("%c", &ch);
            scanf("%c %d %d", &ch, &a, &b);
            if(ch == 'D')
            {
                unite(a, b+n);
                unite(a+n, b);
            }else{
                if(same(a, b)) printf("In the same gang.\n");
                else if(same(a, b+n)) printf("In different gangs.\n");
                else printf("Not sure yet.\n");
            }
        }
    }
    return 0;
}

題目

Find them, Catch them

Time Limit: 1000MS      Memory Limit: 10000K
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
Sample Output

Not sure yet.
In different gangs.
In the same gang.
發佈了151 篇原創文章 · 獲贊 35 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章