0
点赞
收藏
分享

微信扫一扫

Cube Stacking 来源:洛谷

一条咸鱼的干货 2022-02-20 阅读 18

题目

题解

关于这一道题目,想到使用并查集,真的是大神!!!

在这道题目中,通过阅读英文题目,发现它有并查集的影子!

在移动的时候,它是把A所在的一摞(所有的)挪动到B所在的一摞(所有的)的最上面

这就需要快速地判断哪些是在一摞上.

所以猜想使用并查集;

再想:应该把最底下的哪一个叫做根,因为比较稳定

事实上:并查集并不是仅仅用来判断是不是在一个集合里边,还可以有拓展的用途.

(比如记录某一个点到根节点的距离(在这里,我尚且把箱子的个数抽象为距离))

这个距离可以使用一次一次找爸爸的过程来进行求解, 同时还可以路径压缩

代码

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
using namespace std;
#define MAX 30009
int fa[MAX];
int dis[MAX];
int num[MAX];
int find(int x)//注意找的时候要顺便进行路径压缩,在这个过程中,dis的值也要进行更改
//由于这样,所以就不许要在单独设计一个找下面有多少个箱子的函数,直接先来一个find,直接输出dis[i]
{
	if (x != fa[x])//自己不是根节点
		//整个return递归采用了回溯的方法
	{
		int ret = find(fa[x]);
		dis[x] += dis[fa[x]];
		fa[x] = ret;
		return ret;
	}
	else
	{
		return x;
	}
}
void move(int x, int y)
{
	int fx = find(x);
	int fy = find(y);
	fa[fx] = fy;
	dis[fx] += num[fy];
	num[fy] += num[fx];
	
}

int main()
{
	int T;
	scanf("%d", &T);
	for (int i = 1; i <= 30000; i++)
	{
		num[i] = 1;
		fa[i] = i;
	}
	while (T--)
	{
		char buf[12];
		int t1, t2;
		scanf("%s", buf);
		if (*buf == 'M')//移动
		{
			scanf("%d%d", &t1, &t2);
			move(t1, t2);
		}
		else//查询
		{
			scanf("%d", &t1);
			find(t1);
			printf("%d\n", dis[t1]);
		}
	}

	return 0;

}
举报

相关推荐

采药【洛谷】

洛谷python

洛谷3375

拼数(洛谷)

均分纸牌 洛谷

洛谷---统计天数

洛谷——关于我

0 条评论