POJ 1703 - Find them, Catch them

来源:互联网 发布:洛丽塔洋装淘宝 编辑:程序博客网 时间:2024/06/10 09:45

Advanced Data Structures :: Disjoint Set


Description

某个市有两个帮派,且这个市中的所有人,有且仅有在一个帮派中。

告诉你一些信息,即哪两个人不在一个帮派中。

且多次询问两个人,是否在同一个帮派中,或者关系暂时不确定。

对于每个询问,输出询问结果。


Type

Advanced Data Structures :: Disjoint Set


Analysis

利用并查集来解题。

但是并查集通常用来表示,有着相同地位或身份的人,

因为这样的关系有传递性,如你是我的战友,他是你的战友,则我和他也是战友。

而敌对关系没有传递性(你是我的敌人,他是你的敌人,而他不一定是我的敌人),

因此无法用一般的并查集表示。


但是,这样的敌对关系,我们也可以用并查集来表示。

就是将并查集中的边,加权(也可以说是,对每个点增加一个偏移量)。

权值(或者偏移量)用来表示,该节点与父节点的距离

(例如,敌对关系时,距离为1,战友关系则为0),

在同一个并查集森林里,两点之间的距离之和对状态数(上述例子为2)取模,则可以得到两点间的关系。


加权之后,就可以解决这道问题了,并且路径压缩的优化依然可以在加权并查集中使用。


注意当市里只有两个人(不要吐槽)时,这两个人必然是不同团伙的。


Solution

// POJ 1703// Find them, Catch them// by A Code Rabbit#include <cstdio>#include <cstring>const int MAXN = 100002;const int MOD = 2;struct DisjointSet {    int p[MAXN];    int w[MAXN];    void Init(int);    void Make(int x) { p[x] = x; }    int Find(int x) {        if (p[x] == x) return x;        int res = Find(p[x]);        w[x] = (w[x] + w[p[x]]) % MOD;        return p[x] = res;    }    void Union(int x, int y, int d) {        int px = Find(x); int py = Find(y);        p[px] = py;        w[px] = (w[y] - w[x] + d + MOD) % MOD;    }};void DisjointSet::Init(int n) {    memset(w, 0, sizeof(w));    for (int i = 1; i <= n; i++)        Make(i);}int n, m;DisjointSet set;int main() {    int tot_case;       scanf("%d", &tot_case);    while (tot_case--) {        scanf("%d%d", &n, &m);        getchar();        set.Init(n);        for (int i = 0; i < m; i++) {            char ch; int a, b;            ch = getchar();            scanf("%d%d", &a, &b);            getchar();            if (ch == 'D') {                set.Union(a, b, 1);            } else {                int pa = set.Find(a);                int pb = set.Find(b);                if (n == 2) {                    puts("In different gangs.");                    continue;                }                if (pa != pb)                    puts("Not sure yet.");                else                    puts(set.w[a] == set.w[b] ?                        "In the same gang." : "In different gangs.");            }        }    }    return 0;}

原创粉丝点击