POJ 1988 Cube Stacking 并查集

来源:互联网 发布:windows下pyqt4的安装 编辑:程序博客网 时间:2024/04/29 20:09

(题解来自北大2016 ACM/ICPC竞赛训练暑期课讲义)
题目链接:http://poj.org/problem?id=1988
题意:有N(N<=30,000)堆方块,开始每堆都是一个 方块。方块编号1 – N. 有两种操作:
 M x y : 表示把方块x所在的堆,拿起来叠放 到y所在的堆上。
 C x : 问方块x下面有多少个方块。
 操作最多有 P (P<=100,000)次。对每次C操 作,输出结果。
解法:
1.除了parent数组,还要开设 sum数组:记录每堆一共有多少方块。
2. 若parent[a] = a, 则sum[a]表示a所在的堆的 方块数目。
3. under数组,under[i]表示第i个方块下面有多少 个方块。 under数组在 堆合并和 路径压缩的时候都要更 新。
这里写图片描述

#include<iostream>using namespace std;#define maxn 31000int parent[maxn];int sum[maxn]; //若parent[i]=i sum[i]表示砖块i所在堆的砖块数目int under[maxn];int GetParent(int a){    if (parent[a]=a)        return a;    int t=GetParent(parent[a]);    under[a]+=under[parent[a]];    parent[a]=t;    return parent[a];}void Merge(int a,int b){    int n;    int pa=GetParent(a);    int pb=GetParent(b);    if (pa==pb)        return;    parent[pb]=pa;    under[pb]=sum[pa];  //under[pb] 赋值前一定是0,因为 parent[pb] = pb,pb一定是原b所在堆最底下的    sum[pa]+=sum[pb];}int main(){    int p;    for (int i=0;i<maxn;++i)    {        sum[i]=1;        under[i]=0;        parent[i]=i;    }    cin>>p;    for (int i=0;i<p;i++)    {        char s[20];        int a,b;        cin>>s;        if (s[0]=='M')        {            cin>>a>>b;            Merge(b,a);        }        else        {            cin>>a;            GetParent(a);            cout<<under[a]<<endl;        }    }    return 0;}
0 0
原创粉丝点击