zoukankan      html  css  js  c++  java
  • 幷查集拓展

    拓展就是說並不是很明顯的可以套幷查集的模板,或者是要拐個彎的,或者幷查集優化的之類...

    poj 1703.Find them, Catch them

    這題就是兩個團伙,輸入A代表判斷這兩個人是否一個團伙,不同團伙,或者不確定;而輸入D則表示兩個人不是一個團伙;

    如果用幷查集的話,我們一般是合併同一個團伙的,但是我一開始想的是反其道而行,合併不同團伙的,這是可以的,然後再

    用0和1標記一下是否是一個團伙,但是想的很亂,搞了好久沒做出來,結果...發現了一種很神奇的方法,佩服佩服:

    因為是兩個團伙,所以我們把數組擴展一下,比如四個人1,2,3,4,我們把編號擴展成1,2,3,4,5,6,7,8;當輸入1,2不是同一個團伙,

    我們就是1+4=5和2作為一個團伙(5,2),1和2+4=6作為一個團伙(1,6);當再輸入2,3不是一個團伙,那麼(2,7), (6,3),這樣我們

    就找到了(1,6)和(6,3)可以合併到一起,表示(1,3)是一伙的!太巧妙了,怎麼想得到!

     1 // poj 1703.Find them, Catch them
     2 // 并查集 高级
     3 // references:
     4 // http://www.hankcs.com/program/cpp/poj-1703-find-them-catch-them.html 太巧妙了 
     5 #include <iostream>
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <algorithm>
     9 
    10 using namespace std;
    11 
    12 const int N = 200105;
    13 
    14 int p[N];
    15 int n, m;
    16 
    17 void init()
    18 {
    19     for(int i=0; i<N; i++)
    20     {
    21         p[i] = -1;
    22     }
    23 }
    24 
    25 int find(int x)
    26 {
    27     return p[x] == -1 ? x : p[x] = find(p[x]);
    28 }
    29 
    30 void union_set(int u, int v)
    31 {
    32     int x = find(u);
    33     int y = find(v);
    34     if(x != y)
    35     {
    36         p[x] = y;
    37     }
    38 }
    39 
    40 int main()
    41 {
    42     int t;
    43     scanf("%d", &t);
    44     while(t--)
    45     {
    46         init();
    47         scanf("%d%d", &n, &m);
    48         for(int i=0; i<m; i++)
    49         {
    50             getchar();
    51             int u, v;
    52             char s;
    53             scanf("%c%d%d", &s, &u, &v);
    54             if(s == 'A')
    55             {
    56                 if(find(u) == find(v))
    57                 {
    58                     printf("In the same gang.
    ");
    59                 }
    60                 else if(find(u) == find(v + n) || find(u + n) == find(v))
    61                 {
    62                     printf("In different gangs.
    ");
    63                 }
    64                 else
    65                     printf("Not sure yet.
    ");        
    66             }
    67             else
    68             {
    69                 union_set(u, v + n);
    70                 union_set(u + n, v);
    71             }
    72         }
    73     }
    74     return 0;
    75 } 

    最後要注意scanf的緩衝區的問題啊啊啊...輸入%c的時候,注意回車要getchar()掉!!!

  • 相关阅读:
    .net core 3.1 使用Redis缓存
    JavaSE 高级 第11节 缓冲输入输出字节流
    JavaSE 高级 第10节 字节数组输出流ByteArrayOutputStream
    JavaSE 高级 第09节 字节数组输入流ByteArrayInputStream
    JavaSE 高级 第08节 文件输出流FileOutputStream
    JavaSE 高级 第07节 文件输入流FileInputStream
    JavaSE 高级 第06节 初识I、O流
    JavaSE 高级 第05节 日期类与格式化
    JavaSE 高级 第04节 StringBuffer类
    JavaSE 高级 第03节 Math类与猜数字游戏
  • 原文地址:https://www.cnblogs.com/dominjune/p/4727355.html
Copyright © 2011-2022 走看看