IT民工
加油!

第一次做这种类型的并查集。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;
}

 

 

posted on 2012-07-27 17:26  找回失去的  阅读(185)  评论(0)    收藏  举报