【代码超详解】POJ 3026 Borg Maze(优先队列 BFS + 最小生成树,0 ms)

一、题目描述

在这里插入图片描述

二、算法分析说明与代码编写指导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
法一
对每个点 S 和 A 各做一次 BFS 求得单源最短路。用求得的全部结果建图,求解最小生成树。
法二
用一次带优先队列的 BFS 代替暴力 n 次 BFS。原理是:
从起点开始做 BFS。找到第一个 A(设到 S 的距离为 D)后,记这个 A 点到它本身距离为 0(到其它点的距离未知),压入优先队列 q。于是,接下来出队的总是 A 及其周围的距离 A 小于 D 的可达点,而其它点都不会出队。
实现时要注意,队列的每个节点都带有起始节点成员,用两个坐标 sx 和 sy 表示。当点 (x, y) 有外星人 A(可以不包括起点 S,因为 S 到每个 A 都会连一条边,不影响最终建图)时,连一条对应起点 <(sx, sy), (x, y)> 的有向边(边的方向不影响最后求解最小生成树)。然后将这点的距离成员 d 标记为 0 再压入队列,而不要直接在 d 数组上标记,否则会因为 d 被标记为 0,从而该点到最近的 A 点的距离无法再更新,导致建图不完全。同样,取某点的距离 D 时,要取队首元素内存储的距离成员 d 的值,否则会导致取到的距离偏大,因为每个 A 点的位置在 d 数组中的值都不是 0。
最后的 d 数组中,每个点对应的值是到最近的 A 点的距离大小。
BFS 完成后,建图就完成了,直接套模板求最小生成树。
本代码中,为与题目给的坐标意义切合(y 行 x 列字符),二维数组的第一个点是纵坐标。

三、AC 代码(0 ms)

法二:

#include<cstdio>
#include<algorithm>
#include<queue>
#pragma warning(disable:4996)
using namespace std;
template<size_t n> class union_find {
   
private:
	unsigned root[n]; int rank[n];
public:
	union_find<n>() {
    init(); }
	union_find<n>(const bool& WannaInit) {
    if (WannaInit == true)init(); }
	void init() {
   
		fill(rank, rank + n, 1); for (unsigned i = 0; i < n; ++i)root[i] = i;
	}
	void init(const size_t& _n) {
   
		fill(rank, rank + _n, 1); for (unsigned i = 0; i < _n; ++i)root[i] = i;
	}
	unsigned find_root(const unsigned& v) {
   
		unsigned r = v, t = v, u;
		if (t == root
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值