题解 P5092 【[USACO04OPEN]Cube Stacking】

对于每个方块 \(x\) ,

\(cnt_x\) 代表以 \(x\) 为根结点的方块的个数,(即x是一幢方块的顶,问这幢方块一共有几个。)

\(dis_x\) 表示 \(x\) 到根节点的距离。(即x头上顶着多少个方块)

题解 P5092 【[USACO04OPEN]Cube Stacking】

#include<bits/stdc++.h>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define per(i,x,y) for(int i=x;i>=y;i--)
#define rd(x) scanf("%d",&x);
typedef long long LL;
const int N=30010;
int n=30000;
int dis[N],fa[N],cnt[N];
int find(int x){
	if(x==fa[x]) return x;
	int f=find(fa[x]);
	dis[x]+=dis[fa[x]];
	fa[x]=f;
	return fa[x];
}
void merge(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx==fy) return;
	fa[fy]=fx;
	dis[fy]=cnt[fx];
	cnt[fx]+=cnt[fy];
} 
int main(){
	for(int i=1;i<=n;i++) fa[i]=i,dis[i]=0,cnt[i]=1;
	int p;scanf("%d",&p);
	while(p--){
		char s[5];int x,y;
		scanf("%s",s);
		if(s[0]=='M'){
			scanf("%d%d",&x,&y);
			merge(x,y);
		} else {
			scanf("%d",&x);
			int fx=find(x);
			printf("%d\n",cnt[fx]-dis[x]-1);
		} 
	}
	return 0;
}

上一篇:二分法求零点


下一篇:洛谷 题解 P1196 【[NOI2002]银河英雄传说】