• 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

  • 相关阅读:
    记一次生产环境Nginx间歇性502的事故分析过程
    如何为nginx配置https(免费证书)
    nginx + tomcat配置https的两种方法
    证书之间的转换(crt pem key)
    FreeSwitch: ESL Inbound内联模式下如何设置单腿变量
    CompletableFuture笔记
    java中整数常量池(-128~127)上限如何调整?
    redis过期机制及注意事项
    一次完整的通话过程SIP报文分析
    SIPp测试freeswitch用户注册
  • 原文地址:https://www.cnblogs.com/sench/p/7944384.html
Copyright © 2020-2023  润新知