poj1703 Find them, Catch them(带权并查集)

Posted ColdCode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1703 Find them, Catch them(带权并查集)相关的知识,希望对你有一定的参考价值。

题目链接

http://poj.org/problem?id=1703

题意

有两个帮派:龙帮和蛇帮,两个帮派共有n个人(编号1~n),输入m组数据,每组数据为D [a][b]或A [a][b],D[a][b]表示a,b属于不同的帮派,A [a][b]则让我们判断a,b是否属于一个帮派,根据判断的结果进行相应的输出。

思路

这题和poj2492很像,使用并查集解决,方法我已在poj2492的题解中写出,这里不再赘述。

代码

 1 #include <cstdio>
 2 using namespace std;
 3 
 4 const int N = 100000 + 10;
 5 int p[N];
 6 int r[N];
 7 
 8 void make_set(int n)
 9 {
10     for (int i = 1;i <= n;i++)
11     {
12         p[i] = -1;
13         r[i] = 0;
14     }
15 }
16 
17 int find_root(int x)
18 {
19     if (p[x] == -1)
20         return x;
21 
22     int t = p[x];
23     p[x] = find_root(p[x]);
24     r[x] = (r[x] + r[t]) % 2;
25     return p[x];
26 }
27 
28 void union_set(int a, int b)
29 {
30     int ra = find_root(a);
31     int rb = find_root(b);
32 
33     if (ra != rb)
34     {
35         p[ra] = rb;
36         r[ra] = (r[a] + r[b] + 1) % 2;
37     }
38 }
39 
40 int main()
41 {
42     //freopen("poj1703.txt", "r", stdin);
43     int t;
44     scanf("%d", &t);
45     while (t--)
46     {
47         int n, m;
48         scanf("%d%d", &n, &m);
49         make_set(n);
50         char c;
51         int a, b;
52         for (int i = 0;i < m;i++)
53         {
54             getchar();
55             scanf("%c%d%d", &c, &a, &b);
56             if (c == \'A\')
57             {
58                 if (find_root(a) == find_root(b))    //a,b在一个集合里
59                 {
60                     if (r[a] == r[b])    //a,b为同一帮派
61                         puts("In the same gang.");
62                     else puts("In different gangs.");    //a,b为不同帮派
63                 }
64                 else puts("Not sure yet.");    //a,b不再同一集合里,故不确定
65             }
66             else union_set(a, b);
67         }
68     }
69     return 0;
70 }

注意点

1、函数union_set要写成这样:

//正确写法
void union_set(int a, int b)
{
    int ra = find_root(a);
    int rb = find_root(b);

    if (ra != rb)
    {
        p[ra] = rb;
        r[ra] = (r[a] + r[b] + 1) % 2;
    }
}

写成如下形式会MLE:

//错误写法,MLE
void union_set(int a, int b)
{
    int ra = find_root(a);
    int rb = find_root(b);

    p[ra] = rb;
    r[ra] = (r[a] + r[b] + 1) % 2;
}

2、使用scanf输入。

相似题目

1、poj2492

以上是关于poj1703 Find them, Catch them(带权并查集)的主要内容,如果未能解决你的问题,请参考以下文章

POJ1703 Find them, Catch them

poj-1703-Find them, Catch them

poj 1703 Find them, Catch them

(POJ 1703)Find them, Catch them

POJ 1703 Find them,Catch them

[并查集] POJ 1703 Find them, Catch them