bzoj 3376: [Usaco2004 Open]Cube Stacking 方块游戏 带权并查集

来源:互联网 发布:淘宝海外集运 编辑:程序博客网 时间:2024/06/06 06:56

题意

约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.
游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种:
1.移动(M):将包含X的立方柱移动到包含Y的立方柱上.
2.统计(C):统计名含X的立方柱中,在X下方的方块数目.
写个程序帮贝茜完成游戏.

分析

直接上带权并查集即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=30005;int dis[N],m,f[N],size[N];int get_dis(int x){    int ans=0;    while (f[x]!=x) ans+=dis[x],x=f[x];    return ans+dis[x];}int find(int x){    while (f[x]!=x) x=f[x];    return x;}void merge(int x,int y){    int fx=find(x),fy=find(y);    if (size[fx]<size[fy]) dis[fx]+=size[fy]-dis[fy],size[fy]+=size[fx],f[fx]=fy;    else dis[fy]-=dis[fx],dis[fx]+=size[fy],dis[fy]-=size[fy],size[fx]+=size[fy],f[fy]=fx;}int main(){    for (int i=1;i<=30000;i++) f[i]=i,size[i]=1;    scanf("%d",&m);    while (m--)    {        char op[2];        scanf("%s",op);        if (op[0]=='M')        {            int x,y;            scanf("%d%d",&x,&y);            merge(x,y);        }        else        {            int x;            scanf("%d",&x);            printf("%d\n",get_dis(x));        }    }    return 0;}
原创粉丝点击