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()掉!!!

  • 相关阅读:
    toj 2975 Encription
    poj 1797 Heavy Transportation
    toj 2971 Rotating Numbers
    zoj 2281 Way to Freedom
    toj 2483 Nasty Hacks
    toj 2972 MOVING DHAKA
    toj 2696 Collecting Beepers
    toj 2970 Hackle Number
    toj 2485 Card Tric
    js页面定位,相关几个属性
  • 原文地址:https://www.cnblogs.com/dominjune/p/4727355.html
Copyright © 2011-2022 走看看