POJ 1988 Cube Stacking——并查集

比较巧妙的并查集,考察对并查集的引申应用。维护三个数组:

a[i]表示i到pre[i]中间有方块的个数

pre[i]表示i所在集合编号,即根

c[i]表示以i为标志的集合中元素个数,只有当pre[i]=i的时候c[i]才有意义

合并时,只需进行如下操作:

1、对读入的x、y分别进行路径压缩,直到找到真根为止

2、合并x、y两个集合,主要步骤如下:

    pre[x]:=y;a[x]:=c[y];c[y]:=c[y]+c[x];

这道题目倒是和银河英雄传说有些相似之处,可以对比着来做一下。

 

Program Cubes;//By_Poetshy
Const
	maxn=30000;
Var
	i,n,p,q						:Longint;
	pre,a,c						:Array[1..maxn]of Longint;
	ch							:Char;
	
Procedure Combine(x,y:Longint);
begin
	pre[x]:=y;
	a[x]:=c[y];
	inc(c[y],c[x]);
end;
	
Function Find_Set(i:Longint):Longint;
var fa:Longint;
begin
	if pre[i]=i then exit(i);
	fa:=pre[i];
	pre[i]:=Find_Set(pre[i]);
	inc(a[i],a[fa]);
	exit(pre[i]);
end;
	
Procedure Union(p,q:Longint);
begin
	Combine(Find_Set(p),Find_Set(q));
end;
	
BEGIN
	readln(n);
	for i:=1 to maxn do
		begin
			pre[i]:=i;c[i]:=1;a[i]:=0;
		end;
	for i:=1 to n do
		begin
			read(ch);
			if ch='M' then
				begin
					readln(p,q);
					Union(p,q);
				end else
					begin
						readln(p);
						pre[p]:=Find_Set(p);
						writeln(a[p]);
					end;
		end;
END.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值