zoukankan      html  css  js  c++  java
  • POJ1988(带权并查集,搬砖块)

    题意:
           可以这样理解,有n快方形积木,一开始都是单独的放到哪,然后有两种操作
    1 M a b 把a所在的那一堆落到b所在那一堆的上面(一开始自己是一堆)
    2 C a 问a下面有多少个积木


    思路: 
           感觉很久以前杭电上见过这个题目,比较简单的带权并查集,我们可以维护两个权来满足要求,第一个就是记录集合元素个数,就是合并的时候更新a所在的祖宗节点的距离权值,第二个权值就是距离权值,记录每个元素距离根节点的距离,然后更新就是简单更新没啥说的,还有就是简简单单敲完提交后WA了一发,哎!丢脸,还好不是比赛,让我想起了有一场亚洲赛的水题我果断敲完,然后上去1WA。这个题目我WA是因为忘记了输出距离权值前要先查询一下,也就是更新一下,因为用了路径压缩,路径压缩的最理想状态是一个点,四周连着所有本集合的其他点,但是要想把一个路径上压缩成一对多,起码要查询就是更新一便,因为在动态的更新的时候当前所有状态并是不理想路径压缩后的状态,这个自己画画很容易理解,哎!记得当时还经常给小学弟讲这个问题呢!。


    #include<stdio.h>


    #define N 30000 + 10


    int mer[N] ,sum[N] ,s_x[N];


    int Finds(int x)
    {
        if(x == mer[x]) return x;
        int t = mer[x];
        mer[x] = Finds(mer[x]);
        s_x[x] += s_x[t];
        return mer[x];
    }


    int main ()
    {
        int m ,i ,x ,y ,a ,b;
        char str[5];
        for(i = 1 ;i <= 30000 ;i ++)
        s_x[i] = 0 ,sum[i] = 1 ,mer[i] = i;
        scanf("%d" ,&m);
        for(i = 1 ;i <= m ;i ++)
        {
            scanf("%s" ,str);
            if(str[0] == 'M')
            {
                scanf("%d %d" ,&a ,&b);
                x = Finds(a);
                y = Finds(b);
                s_x[x] = sum[y];
                sum[y] += sum[x];
                mer[x] = y;
            }
            else
            {
                scanf("%d" ,&a);
                Finds(a);
                printf("%d " ,s_x[a]);
            }
        }
        return 0;
    }





  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/csnd/p/12062483.html
Copyright © 2011-2022 走看看