POJ 1988 Cube Stacking

本文介绍了一种使用并查集解决堆合并问题的方法。通过将不动的堆视为根节点,移动的堆连接到不动堆上,并更新移动堆的根节点的下部节点数量,以此来维护堆的状态。这种方法可以高效地处理堆合并操作。

初始时每个堆就一个方块,如果碰到指令M,那么就是把x的堆放到y的堆上,那么我们把不动的堆,也就是y当作根,把x解到y上,那么x堆的根结点的under[rootx]改成

y堆的sum[rooty],因为x堆下面最起码有sum[rooty]的方块,y的每个方块的under是不用更新的,因为它没有变,而x堆的方块则需要更新,更新的方法就是如果你要知道

p下面有多少个节点时,从p开始去寻找根结点,然后把找到的每个节点的under值都相加。因为这条路上的几点都是之前的根结点,他们之前移动时,已经被更新成了sum[rooty],也就是被移动到的堆的总结点数,所以这一路上相加之后,就是p的under值了。

这种思路解题的最关键因素时,需要把不动的结点当做根结点,动的结点接上去,并把动的堆的根结点的under值更新为不动堆的总结点数,方便相加。

//
//  main.cpp
//  Richard
//
//  Created by 邵金杰 on 16/7/1.
//  Copyright © 2016年 邵金杰. All rights reserved.
//


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=30000+1000;
int pa[maxn],sum[maxn],under[maxn];
int getroot(int a)
{
    if(pa[a]==a) return a;
    int t=getroot(pa[a]);
    under[a]+=under[pa[a]];
    pa[a]=t;
    return pa[a];
}
void merge(int a,int b)
{
    int root1=getroot(a);
    int root2=getroot(b);
    if(root1==root2) return ;
    pa[root2]=root1;
    under[root2]=sum[root1];
    sum[root1]+=sum[root2];
}
int main()
{
    int t,x,y;
    char cmd[10];
    cin>>t;
    for(int i=0;i<maxn;i++) {sum[i]=1;pa[i]=i;under[i]=0;}
    while(t--)
    {
        scanf("%s",cmd);
        if(cmd[0]=='M') {cin>>x>>y;merge(x,y);}
        else {cin>>x;getroot(x);cout<<under[x]<<endl;}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值