POJ 1703 Find them, Catch them(分类并查集)

来源:互联网 发布:西门吹牛中淘宝店 编辑:程序博客网 时间:2024/06/08 09:26

Description

在这个城市里有两个黑帮团伙,现在给出n个人,每个人都属于这两个帮派中的一个,m次操作,操作分两种:
1.D x y:x于y不在一个团伙里
2.A x y:查询x与y的关系,即是否在同一团伙或者不确定

Input

第一行一个整数T表示用例组数,每组用例第一行为两个整数n和m分别表示人数和操作数,之后m行每行表示一种操作(1<=n<=100000)

Output

对于每次查询,如果两个人在一个团伙则输出”In the same gang.“,如果两个人不在一个团伙则输出”In different gangs.“,如果不确定则输出”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.

Solution

并查集,食物链弱化版,对每个人i建立两个元素i和i+n分别表示这个人属于团伙1和团伙2,则
1.两个人不属于同一团伙:unite(x,y+n),unite(x+n,y)
2.判断两人是否属于同一团伙:same(x,y)表示x和y属于同一团伙,same(x,y+n)表示x和y属于不同团伙,两者都不成立说明x和y关系不确定

#include <iostream>#include <cstdio>#include <map>#include <vector>using namespace std;const int n = 100010;int pre[n + n] = {0};int find(int x){    if (x == pre[x])    {        return x;    }    return pre[x] = find(pre[x]);}void join(int i, int j){    int iRoot = find(i);    int jRoot = find(j);    if (iRoot != jRoot)    {        pre[jRoot] = iRoot;    }}void init(){    for (int i = 1; i <= n + n - 1; i++)    {        pre[i] = i;    }}bool same(int a, int b){    return find(a) == find(b);}int main(){    int Case;    cin >> Case;    while (Case--)    {        int id_sum, lines;        cin >> id_sum >> lines;        init();        while (lines--)        {            char chr;            int a, b;            getchar();            scanf("%c%d%d", &chr, &a, &b);            if (chr == 'A')            {                if (same(a, b) || same(a + n, b + n))                {                    cout << "In the same gang." << endl;                }                else if (same(a, b + n) || same(a + n, b))                {                    cout << "In different gangs." << endl;                }                else                {                    cout << "Not sure yet." << endl;                }            }            else if (chr == 'D')            {                join(a, b + n);                join(a + n, b);            }        }    }    return 0;}