• POJ 1703 Find them, Catch them


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

    应该是书上例题(食物链 POJ1822)的简单版

    这里同样用书上很巧妙的思路

    如何表达 在集合A 和 集合B 中

    并不是 让i.set = A  类似于这样活着P[i] = A

    而是将 这个变成一个隐形条件 并且 不用再关心 i到底是在A集合 还是在B集合 

    建立并查集par[2*N] 

    让i 表示在集合A 中 i +N 表示在集合B 中

    当两个数在同一集合(有共同根节点)时 说明这样的时间必然发生

    及如果same(i, j+N) 则说明 i 在集合A中 j在集合B中 --->>>>i j 一定不再同一个集合中

    这样简化问题 不再纠结于 i到底是在A 还是在B 而是针对问题 操作 

    注意不要用cin 会超时

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define N 100007
     5 using namespace std;
     6 
     7 int par[2*N];
     8 int rank[2*N];
     9 int find(int x)
    10 {
    11     if (x == par[x]) return x;
    12     else return par[x] = find(par[x]);
    13 }
    14 
    15 void unite(int x, int y)
    16 {
    17     int px = find(x), py = find(y);
    18     if (px == py) return ;
    19     else if (rank[px] > rank[py])
    20     {
    21         par[py] = px;
    22     }
    23     else
    24     {
    25         par[px] = py;
    26         if (rank[px] == rank[py]) rank[py]++;
    27     }
    28 }
    29 
    30 bool same(int x, int y)
    31 {
    32     int px = find(x), py = find(y);
    33     return px == py;
    34 }
    35 int main()
    36 {
    37     int T, n, M;
    38     freopen("in.txt", "r", stdin);
    39     scanf("%d", &T);
    40     while(T--)
    41     {
    42         scanf("%d%d", &n, &M);
    43         for (int i = 1;i <= 2*n; i++)
    44         {
    45             par[i] = i;
    46             rank[i] = 1;
    47         }
    48         char ch;
    49         int a, b;
    50         for (int i = 0; i < M; i++)
    51         {
    52             //cin >> ch;//用cin 读取 char 可以避免换行符 但是会超时 因为 输入规模比较大
    53             getchar();
    54             scanf("%c", &ch);
    55             scanf("%d%d", &a, &b);
    56             if (ch == 'A')
    57             {
    58                 if ( same(a, b) || same(a, b+n) )
    59                 {
    60                     if ( same(a, b) ) printf("In the same gang.
    ");
    61                     else printf("In different gangs.
    ");
    62                 }
    63                 else printf("Not sure yet.
    ");
    64             }
    65             else
    66             {
    67                 unite(a, b+n);
    68                 unite(a+n, b);
    69             }
    70         }
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    一份详尽的 Java 问题排查工具清单,值得收藏!
    专业解决 MySQL 查询速度慢与性能差!
    马士兵对话京东T6阿里P7(薪水):月薪5万,他为何要离职?
    Java中的注解到底是如何工作的?
    一道简单的面试题,难倒各大 Java 高手!
    疯狂618,当当买书打 3 折!
    SQL才是世界上最牛逼的语言!
    程序员必须掌握的职场黑话,你知道几个?
    面试问我 Java 逃逸分析,瞬间被秒杀了。。
    redis 介绍与操作
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6395905.html
Copyright © 2020-2023  润新知