zoukankan      html  css  js  c++  java
  • 初涉「带权并查集」&&bzoj3376: [Usaco2004 Open]Cube Stacking 方块游戏

    算是挺基础的东西

    Description

        约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.
       游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种:
        1.移动(M):将包含X的立方柱移动到包含Y的立方柱上.
        2.统计(C):统计名含X的立方柱中,在X下方的方块数目.
        写个程序帮贝茜完成游戏.

    Input

        第1行输入P,之后P行每行输入一条指令.形式为“M X Y”或者“C X”
        输入保证不会有将立方柱放在自己头上的指令.

    Output

        每一行,对于每个统计指令,输出其结果.

    Sample Input

    6
    M 1 6
    C 1
    M 2 4
    M 2 6
    C 3
    C 4

    Sample Output

    1
    0
    2

    题目分析

    带权并查集的模板题。

    之所以能够用并查集做,是因为:即便集合内每一个元素不是完全等价的,但它满足能够独立带权的性质。

    嗯……如果是初学带权并查集的话还是无视上面那句话好了。学的时候还是靠代码理解,理解之后自然就会有自己对于一块方面的总结了。

    对于每一个维护$dis[i]$和$sum[i]$,其中$dis[i]$表示它下面有几个方块;$sum[i]$表示它这摞方块一共有几个。维护两个量是为了方便合并时的转移。

    因为这题有上下之分,所以合并过程是既不能随便合并(破坏顺序);也难以按秩合并(麻烦)。路径压缩看上去好像也不行,然而实际上可以这样操作:保留逻辑上的上下顺序(换句话说,就是我们在考虑问题时候当做它是上下有序),但是操作时就路径压缩(运行结果上来看,元素之间路径被压缩了,因此并没有上下顺序)。

    这样便发现,合并时候把整摞方块的最下面方块作为根是更方便的。

     1 #include<cstdio>
     2 #include<cctype>
     3 const int maxn =  30035;
     4 
     5 int fa[maxn],sum[maxn],dis[maxn];
     6 int q;
     7 
     8 int get(int x)
     9 {
    10     if (fa[x]!=x){
    11         int tt = fa[x];
    12         fa[x] = get(fa[x]);
    13         dis[x] += dis[tt];
    14     }
    15     return fa[x];
    16 }
    17 void unions(int x, int y)
    18 {
    19     fa[x] = y;
    20     dis[x] += sum[y];
    21     sum[y] += sum[x];
    22 }
    23 int main()
    24 {
    25     scanf("%d",&q);
    26     for (int i=1; i<=30000; i++) fa[i] = i, sum[i] = 1;
    27     for (int i=1; i<=q; i++)
    28     {
    29         char ch = getchar();
    30         while (!isalpha(ch)) ch = getchar();
    31         int x,y;
    32         if (ch=='M'){
    33             scanf("%d%d",&x,&y);
    34             int fx = get(x), fy = get(y);
    35             if (fx!=fy) unions(fx, fy);
    36         }else{
    37             scanf("%d",&x);
    38             get(x);
    39             printf("%d
    ",dis[x]);
    40         }
    41     }
    42     return 0;
    43 }

    END

  • 相关阅读:
    SQL server分离和附加数据库
    sql-server的添加数据库文件(日志数据)以及收缩数据库文件(日志数据)
    sql语句中的join用法(可视化解释)
    SQL语句(floor、ceiling和round以及left和right)
    怎样重新获得别人的信任-知识就是力量(思维导图)
    怎样让孩子爱上学习-知识就是力量(思维导图)
    洛谷-P1036 选数
    洛谷-P1028 数的计算
    洛谷-P1914 小书童——密码
    洛谷-P1598 垂直柱状图
  • 原文地址:https://www.cnblogs.com/antiquality/p/9316386.html
Copyright © 2011-2022 走看看