POJ 1703 Find them, catch them (並查集)

  題目: Find them,Catch themios

  剛開始覺得是最基本的並查集,無限超時。spa

  這個特殊之處,就是可能有多個集合。code

  好比輸入D 1 2  D 3 4 D 5 6...這就至少有3個集合了。而且任意2個集合之間成員的敵我關係不明。blog

  這裏每一個集合裏面的成員關係要記錄,他們在一個集合裏,只是由於他們關係明確,敵人或者朋友。get

  千萬不要簡單的認爲成朋友在一個集合,敵人在另一個集合,分紅2個集合。由於題目說只有2個匪幫,很容易進入這個誤區。io

  咱們只要記錄一個成員和本身父親的敵我關係和建樹就能夠了。class

  

代碼:stream

#include<iostream>
#include<cstdio>
using namespace std;
const int MM = 100001;
int father[MM];
int relation[MM];


int find(int x)
{
    if(x == father[x]) return x;
    int r = find(father[x]);
    relation[x] ^= relation[father[x]];
    return father[x] = r;
}

void join(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    
    father[fx] = fy;
    if(relation[y] == 1)
        relation[fx] = relation[x]; 
    else
        relation[fx] = 1 - relation[x];
}


void solve()
{
    int T,N,M,i,a,b,ta,tb;
    char str;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d",&N, &M);
        
        for(i = 1; i <= N; ++i)
        {
            father[i] = i;
            relation[i] = 0;
        }
        
        for(i = 0; i < M; ++i)
        {
            getchar();
            scanf("%c %d %d", &str, &a, &b);
            if(str == 'D')
                join(a, b);
            else
            {
                ta = find(a);
                tb = find(b);
                if(ta == tb)
                {
                    if(relation[a] == relation[b])
                        printf("In the same gang.\n");
                    else
                        printf("In different gangs.\n");
                }   
                else
                    printf("Not sure yet.\n");
            }
        }
    }
}

int main()
{
    solve();
    return 0;
}
相關文章
相關標籤/搜索