POJ 1988 : Cube Stacking - 简单并查集

题意:

N(N<=30,000)堆方块,开始每堆都是一个方块。方块编号1–N.有以下两种操作:M x y :表示把方块x所在的堆,拿起来叠放到y所在的堆上。C x : 问方块x下面有多少个方块。操作最多有P (P<=100,000)次。对每次C操作,输出结果。

输入:

M x y :表示把方块x所在的堆,拿起来叠放到y所在的堆上。

C x : 问方块x下面有多少个方块。

输出:

C的结果。

思路:

除了par数组,还要开设辅助数组:

sum[]:记录每堆一共有多少方块,par[a] = a, sum[a]表示a所在的堆的方块数目。

under[] under[i]表示第i个方块下面有多少个方块。under数组在堆合并和路径压缩的时候都要更新。


小结:并查集有两种,一种是关系式,一种是数量式。这里是后者。需要开辅助数组求解。


闲话二三:

这些天事情真多,写着写着总是错,参考着前人的,终于A掉了。

#include<iostream>
#include<cstdio>
using namespace std;
const int N=30050;
int sum[N],under[N],par[N];

void init();
void merge(int a,int b);
int find_set(int a);
int query(int a);

int main(){
	int p;
	scanf("%d",&p);
	init();
	while(p--){
		char op;
		int x,y,i;
		scanf("\n%c",&op);//这种读入方式要学习
		if(op=='M'){
			scanf(" %d %d",&x,&y);
			merge(x,y);
		}
		else{
			scanf("%d",&x);
			find_set(x);
			printf("%d\n",under[x]);
		}
	}
	return 0;
}

void init(){//	ok
	for(int i=1;i<=N;i++){
		par[i]=i;
		sum[i]=1;
		under[i]=0;
	}
}
void merge(int a,int b){// C a b
	a=find_set(a);
	b=find_set(b);
	if(a==b) return;
	par[a]=b;
	//sum[b]=sum[a];
	under[a]+=sum[b];//这个函数容易出错,因为a,b相互的操作。并非纯并查集模版类型的操作。
	sum[b]+=sum[a];
}
int find_set(int a){
	int tmp=par[a];
	if(par[a]!=a){
		par[a]=find_set(par[a]);
		under[a]+=under[tmp];
	}
	return par[a];
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值