poj 1988 Cube Stacking【带权并查集】

题意:初始时有N堆砖块,每堆有一个(编号为1-N)。现在有q个操作,
操作分2种:
M X Y 将含编号X的那堆放置在编号为Y堆的上方
C X 含编号为X的砖块下方有多少个砖块

思路:在普通并查集的基础上加了两个变量:sum,top。用sum去维护某砖块下方的砖块数(代码实现过程中,实际上当前结点的sum值只记录到了它的当前父亲结点fa处的砖块个数,所以查询时需要先更新一下);top维护每个砖块所在位置最上方的砖块编号,因为每次进行第一种操作时,是把X所在的那一堆砖块放在Y所在那一堆砖块中最高砖块上
在这里插入图片描述
实际上我们字也只需要更新记录每一个父亲结点的top值。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int manx=3e4+10;
struct node
{
    int fa,sum,top;
    node()
    {
        sum=0;
    }
}p[manx];

int find(int x)//查找根结点
{
    if(x==p[x].fa)return x;
    int temp=find(p[x].fa);
    p[x].sum+=p[p[x].fa].sum;
    //注意带权并查集中记录权值的变量都是在回溯的过程中更新的
    return p[x].fa=temp;
}

int main()
{
    char ope[2];
    int n,x,y;
    scanf("%d",&n);
    for(int i=1;i<=manx;i++)
    {
        p[i].fa=i;
        p[i].top=i;
    }
    while(n--)
    {
        scanf("%s",ope);
        if(ope[0]=='M')
        {
            scanf("%d%d",&x,&y);
            int fx=find(x);
            int fy=find(y);
            if(fx==fy)
                continue;
            p[fx].fa=p[fy].top;
            p[fx].sum=1;
            p[fy].top=p[fx].top;
        }
        else
        {
            scanf("%d",&x);
            find(x);
            printf("%d\n",p[x].sum);
        }
    }
}
发布了52 篇原创文章 · 获赞 26 · 访问量 3159

猜你喜欢

转载自blog.csdn.net/qq_43803508/article/details/103773681