搭积木 并查集 洛谷P2342 叠积木

现在有一排n(n<=300000)个积木,按顺序从1到n编号,我们想把这些积木堆起来。

刚开始的时候,n个积木每一个是单独的柱子,接下来我们会进行m次操作,把这些积木堆成更高的柱子。

有两种操作类型:

1.将x好积木所在的柱子按照原顺序堆到y号积木所在的柱子上面

2.计算x号积木所在的柱子当中,堆在x积木之下的积木个数

Input

第一行一个正整数m,不会给出n的值

接下来m行,每行描述一个操作,如果这一行以M开头,那么接下来两个正整数x,y表示进行一次操作1;如果以C开头,接下来一个正整数x,表示进行一次操作2。

Output

输出若干行,表示每一次操作2的答案

Constraints

对于40%的数据 m<200

对于100%的数据 m<100000

 

一眼看出并查集(不解释)

洛谷有一道很相似的题目:银河英雄传说

我们每次进行操作1,将x与y所在的并查集合并

操作2输出x下的积木个数

在这中间进行一些处理就好了(好像什么也没说)

在上课没时间好好写注释了(っ•̀ω•́)っ✎⁾⁾ 我爱学习

更新:洛谷发现原题:叠积木P2342

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=30010;
int pre[maxn];
int m;
int deep[maxn];
int under[maxn];
int findpa(int a)
{
    if(pre[a]==a) return a;
    int fa=findpa(pre[a]);
    under[a]+=under[pre[a]];
    return pre[a]=fa;
}
void step1(int x,int y){
    int xx=findpa(x);
    int yy=findpa(y);
    if(xx==yy) return;
    under[xx]+=deep[yy];
    deep[yy]+=deep[xx];
    deep[xx]=0;
    pre[xx]=yy;
    return;
}
void step2(int x)
{    
    int xx=findpa(x);
    cout<<under[x]<<endl;
}

void read(){
    for(int i=1;i<=maxn;i++) pre[i]=i,under[i]=0,deep[i]=1;
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        char c;
        cin>>c;
        if(c=='M') {cin>>x>>y;step1(x,y);} 
        if(c=='C') {cin>>x;step2(x);} 
    }
}
int main(){
    //freopen("cubes.in","r",stdin);
    //freopen("cubes.out","w",stdout);
    read();
    return 0;
}

 

posted @ 2018-10-01 15:13  cheng-qing  阅读(339)  评论(0编辑  收藏  举报