算法竞赛进阶指南---0x41 (并查集) 银河英雄传说

题面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题解

  1. 题中有两种操作方式,一种是合并两个集合,一种是询问集合中元素的关系(距离),那就是并查集,而且是要维护到祖宗节点距离的并查集
  2. 先看查询操作,我们可以用一个d[x] 数组维护 x 到 p[x] 的距离 ,在每次 find(x) 操作之后 +路径压缩,那么x到p[x] 的距离就是 x 到祖宗节点的距离,如果两个战舰x,y在同一个集合中,abs(d[x]-d[y])-1不就是两个战舰之间还有多少个战舰,如果不在就返回-1
  3. 接下来就考虑如何维护 d 数组,也就是合并操作,假设合并两个战舰集合x,y , px=find(x) ,py=find(y),将以px为祖宗节点的集合合并在以py为祖宗节点集合的后面,那么首先px的祖宗节点就变成了py ,就是p[px]=py,然后维护d集合,对于py集合中的距离肯定是没有变化的,对于px集合中,因为祖宗节点换成了py,所以相应的到祖宗节点的距离也应该更新,原来px中d[x]表示x到px的距离,现在只要加上py中元素的个数,就是x到py(新祖宗节点)的距离了,即d[px]+=s[py]; 由于py集合中新加了px集合,所有py集合中元素的个数也应该增加,即s[py]+=s[px];
  4. 重在自己画图理解,具体看代码

代码

#include<bits/stdc++.h>

using namespace std;
const int N = 3e4 + 10;

int p[N]; //并查集
int s[N]; //集合中战舰的数量
<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值