POJ 1703 Find them, Catch them

第一次做这种类型的并查集。re数组代表所在的类,因为只能从当前情况来判断两个人是

不是在一个犯罪集团。所以D操作时保证两个人的re不同。两个有相同的根结点,代表情况

已知,否则为情况未知。

/*Accepted    948K    360MS    C++    1190B    2012-07-27 17:16:34*/

#include<cstdio>

#include<cstring>

#include<cstdlib>



const int MAXN = 100111;

int p[MAXN], re[MAXN];

int n, m;

char ans[3][20] = {"In different gangs.", "In the same gang.", "Not sure yet."};



void init()

{

    for( int i = 0; i <= n; i ++)

    {

        p[i] = i, re[i] = 0;

    }

}



int find_set( int x)

{

    if(p[x] == x) return x;

    int parent = find_set(p[x]);

    re[x] = (re[x] + re[p[x]]) & 1; //子孙与根结点的re不同

    return p[x] = parent;

}



void union_set( int x, int y)

{

    int nx = find_set(x), ny = find_set(y);

    p[nx] = ny;

    re[nx] = (re[x] + re[y] + 1) & 1; //更新re值

}



int judge(int x, int y)

{

    int nx = find_set(x), ny = find_set(y);

    if( nx == ny) //情况已知

        return re[x] == re[y];

    return 2;

}



void operation()

{

    char op[5];

    while( m --)

    {

        int a, b;

        scanf( "%s%d%d", op, &a, &b);

        if( 'A' == op[0])

        {

            printf( "%s\n", ans[judge(a, b)]);

        }

        else

            union_set(a, b);

    }

}



int main()

{

    int T;

    scanf( "%d", &T);

    while( T --)

    {

        scanf( "%d%d", &n, &m);

        init();

        operation();

    }

    return 0;

}

 

 

你可能感兴趣的:(catch)