• POJ_1703 Find them, Catch them 【并查集】


    一、题面

    POJ1703

    二、分析

    需要将并查集与矢量法则相结合。par数组用以记录父节点,rank用以记录与父节点的关系。如题意,有两种关系,设定0是属于同一个帮派,1表示不属于同一个帮派。

    运用并查集的时候判断x,y时考虑几种情况:

    1.x与y父节点不相同:此时为不清楚两者关系。

    2.x与y父节点相同,rank的值也相同:两者属于同一帮派。

    3.x与y父节点相同,rank的值不相同:两者不属于同一帮派。

    要得到这个关系,需要在并查集的find函数内对各个点的rank和par的值进行不断的更新。

    对于rank,需要使用矢量加法,如

    $overrightarrow{AB}+overrightarrow {BC}=overrightarrow {AC}$

    结合题目就是例:x的父节点px,如果x与父节点的关系是rank[x],px与父节点的关系是rank[px],那么x与par[px]的关系就是

    $(rank[x] + rank[px])\%2$

    其他的推理类似。

    在find的路径压缩时,注意把rank关系进行更新即可,在union时涉及到x,y与它们的父节点px,py的rank值更新,其实原理相同。

    三、AC代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <fstream>
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 1e5+4;
     8 int par[MAXN];
     9 int Rank[MAXN];
    10 
    11 void init()
    12 {
    13     for(int i = 0; i < MAXN; i++)
    14     {
    15         par[i] = i;
    16         Rank[i] = 0;
    17     }
    18 }
    19 
    20 int find(int x)
    21 {
    22     if(par[x] == x)
    23         return x;
    24     int px = par[x];
    25     par[x] = find(par[x]);
    26     Rank[x] = (Rank[px]+Rank[x])%2;
    27     return par[x];
    28 }
    29 
    30 void Union(int x, int y)
    31 {
    32     int px = find(x);
    33     int py = find(y);
    34     if(px == py)
    35         return;
    36     par[px] = py;
    37     Rank[px] = (Rank[x]+1+Rank[y])%2;
    38 }
    39 
    40 int main()
    41 {
    42     //freopen("input.txt", "r", stdin);
    43     //freopen("out.txt", "w", stdout);
    44     int T, M, N, x, y;
    45     char op;
    46     
    47     while(scanf("%d", &T)!=EOF)
    48     {
    49         
    50         while(T--)
    51         {
    52             init();
    53             scanf("%d %d", &N, &M);
    54             for(int i = 0; i < M; i++)
    55             {
    56                 getchar();
    57                 scanf("%c %d %d", &op, &x, &y);
    58                 if(op == 'A')
    59                 {
    60                     int px = find(x);
    61                     int py = find(y);
    62                     if(px != py)
    63                     {
    64                         puts("Not sure yet.");
    65                     }
    66                     else
    67                     {
    68                         if(Rank[x] == Rank[y])
    69                             puts("In the same gang.");
    70                         else
    71                             puts("In different gangs.");
    72                     }
    73                 }
    74                 else
    75                 {
    76                     Union(x, y);
    77                 }
    78             }
    79         }
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    codeforces 617 E. XOR and Favorite Number(莫队算法)
    bzoj 2038 [2009国家集训队]小Z的袜子(hose) 莫队算法
    HDU 6024 Building Shops (简单dp)
    Codeforces Round #417 B. Sagheer, the Hausmeister
    第九届ECNU Coder K.计软联谊
    解决在linux安装网易云音乐无法点击图标打开
    [洛谷P1169] [ZJOI2007]棋盘制作
    [洛谷P2577] [ZJOI2005]午餐
    [洛谷P1941] 飞扬的小鸟
    [洛谷P1600] 天天爱跑步
  • 原文地址:https://www.cnblogs.com/dybala21/p/10134417.html
Copyright © 2020-2023  润新知