您的位置:首页 > 产品设计 > UI/UE

HDU 2818 Building Blocks 带权并查集

2018-01-21 12:15 344 查看
题意:n堆盒子 初始第i堆放盒子i. Q次操作.

操作1: 将包含盒子x的那一堆,放在包含盒子y的那一堆上方.(x,y在同一堆则不操作).

操作2: 算出有多少个盒子在x的下方.

n<=3e4. Q<=1e6.

用并查集把相同堆的盒子连接在一起.cnt[i]维护每个点到其根节点的距离(底部盒子为根)

合并时  cnt[fx]=sum[fy].
以fx为根的节点u,现在以fy为根 在find时 都会先经过fx 在这个时候更新其cnt即可.

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef pair<int,int> ii;
const int N=2e5+5;
int Q,fa
,sum
,cnt
;
void init()
{
rep(i,0,N-1)
fa[i]=i,sum[i]=1,cnt[i]=0;
}
int find(int x)
{
if(x==fa[x])
return x;
int t=find(fa[x]);
cnt[x]+=cnt[fa[x]];
return fa[x]=t;
}
int main()
{
init();
int x,y;
cin>>Q;
while(Q--)
{
char op[2];
scanf("%s",op);
if(op[0]=='M')
{
scanf("%d%d",&x,&y);
int fx=find(x),fy=find(y);
if(fx==fy) continue;
fa[fx]=fy;
cnt[fx]=sum[fy];
sum[fy]+=sum[fx];
}
if(op[0]=='C')
{
scanf("%d",&x);
int fx=find(x);
printf("%d\n",cnt[x]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: