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

  • 相关阅读:
    java基础入门-arraylist存储开销
    java基础入门-iterator迭代器与集合下标的使用
    java基础入门-泛型(1)-为什么需要使用泛型?
    vue路由懒加载
    js防抖和节流
    vue 生命周期函数详解
    createElement 函数
    vue中Runtime-Compiler和Runtime-only的区别
    箭头函数以及this指向问题
    webpackES6语法转ES5语法
  • 原文地址:https://www.cnblogs.com/dominjune/p/4727355.html
Copyright © 2011-2022 走看看