算法_BFS解决多源最短路问题---持续更新

文章目录

  • 前言
  • 引入
  • 矩阵
    • 题目要求
    • 题目解析
    • 代码如下
  • 飞地的数量
    • 题目要求
    • 题目解析
    • 代码如下
  • 地图中的最高点
    • 题目要求
    • 题目解析
    • 代码如下
  • 地图分析
    • 题目要求
    • 题目解析
    • 代码如下

前言

本文将会向你介绍有关宽度优先搜索(BFS)解决多源最短路问题的相关题型:矩阵、飞地的数量、地图中的最高点、地图分析

引入

上一篇文章提到单源最短路问题,单源最短路问题就是给出一个起点,求到终点的最短距离,而多源最短路问题,有多个起点,求到终点的最短路径
多源BFS指的是,用BFS宽度优先搜索解决边权为1的多源最短路问题
那么该如何用BFS解决多个起点求其到终点的最短路这类问题呢?
解法一
将多源最短路问题转化为若干个单源最短路问题,即对每一个起点来一次BFS,但是这样大概率是会超时的

解法二
把所有的起点(源点)当成一个“超级源点”,问题就变成了单一的单源最短路问题
如何转化呢?

1、将所有的起点加入到队列里面
2、一层一层的往外扩展

在这里插入图片描述

矩阵

https://leetcode.cn/problems/2bCMpM/

题目要求

在这里插入图片描述

题目解析

题目要求求出每一个格子到0的最近距离,也就是求1到0的最短路,多个起点求最短路,那么这道题就是一道考察多源BFS的问题

解法一
用单源BFS的思想,即对每一个起点来一次BFS,一层层地向外扩展,这样地做法可能会超时

解法二
多源BFS,即把所有1当作一个超级源点,然后来一次BFS,可是这样也会有一个坑,当找到0后,我们需要更新1位置处的最短距离,每个“1”在遍历时都必须跟踪到最近“0”的距离,找到0后,并不是在0这个位置处标记最短距离,而是返回到1的位置处,这会使实现变得复杂

正难则反
求0到1的最短路问题,因为1到0和0到1的最短路径一定是一样的,只需要先遍历整个矩阵,将0标记出来,然后将所有0添加到队列中一层层向外扩展即可。

如图所示
模拟了一遍向外扩展的过程(绿色为第一次扩展,红色为第二次,蓝色为第三次),已经搜索标记过的区域不需要再标记
在这里插入图片描述

代码如下

class Solution {
public:vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};queue<pair<int, int>> q;vector<vector<int>> dist(mat.size(), vector<int>(mat[0].size(), -1));;for(int i = 0; i < mat.size(); i++){for(int j = 0; j < mat[0].size(); j++){if(mat[i][j] == 0){dist[i][j] = 0;q.push({i, j});}}}while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >= 0 && x < mat.size() && y >= 0 && y < mat[0].size() && dist[x][y] == -1){dist[x][y] = dist[a][b] + 1;q.push({x, y});}}}return dist;}
};

飞地的数量

https://leetcode.cn/problems/number-of-enclaves/

题目要求

在这里插入图片描述

题目解析

题目要求返回被 0 海洋包围的 1 岛屿的个数,如果在边界的岛屿就不算被海洋包围,可以简单地想到遍历矩阵,遇到1,就来一次bfs,找到整块岛屿,但是有个问题,就是区分不了该岛屿是不是在边界上的

证难则反
可以先将边界上的岛屿标记出来,剩下的则全部是被海洋包围的岛屿,即遍历边界上的1,遇到1,就来次bfs,找到整个岛屿并标记,然后两层for循环遍历矩阵即可

代码如下

class Solution {
public:queue<pair<int, int>> q;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};int ret = 0; //飞地的数量//多源bfsvoid bfs(vector<vector<int>>& grid){while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size() && grid[x][y] == 1){grid[x][y]++;q.push({x, y});}}}}int numEnclaves(vector<vector<int>>& grid) {   for(int i = 0; i < grid.size(); i++){for(int j = 0; j < grid[0].size(); j++){if(grid[i][j] == 1 && (i == 0 || i == grid.size() - 1 || j == 0 || j == grid[0].size() - 1)){q.push({i, j});grid[i][j]++;}}}bfs(grid);//统计结果for(int m = 0; m < grid.size(); m++){for(int n = 0; n < grid[0].size(); n++){if(grid[m][n] == 1){ret++;}}}return ret;}
};

地图中的最高点

https://leetcode.cn/problems/map-of-highest-peak/

题目要求

在这里插入图片描述

题目解析

设计出一种安排高度的方案,使得矩阵中的最高高度值最大

1、水域的高度必须为 0
2、任意相邻的格子高度差至多为1

不要被题目所迷惑了,题目说使得矩阵的最高高度最大,如果自己设高度然后推导,这样就踩坑了,实际上从水域开始填充,可以确保陆地的高度逐步增加。这意味着距离水域更远的陆地格子将拥有更高的高度,同时还能满足要求,就能使得矩阵中的最高高度值最大
先将水域高度设置为0,将水域单元格作为一个超级源点,将所有水域单元格添加到队列中,一层层的向外扩展,每次扩展一层都比本层的高度高1

h[x][y] = h[a][b] + 1;

代码如下

class Solution {
public:vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};queue<pair<int, int>> q;vector<vector<int>> h(isWater.size(), vector<int>(isWater[0].size(), -1));  //-1表示格子未被访问过int ret = 0;for(int i = 0; i < isWater.size(); i++){for(int j = 0; j < isWater[0].size(); j++){if(isWater[i][j] == 1)  //将水域高度设置为0{h[i][j] = 0;q.push({i, j});}}}while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >= 0 && x < isWater.size() && y >= 0 && y < isWater[0].size() && h[x][y] == -1){h[x][y] = h[a][b] + 1;q.push({x, y});}}}for(int m = 0; m < grid.size(); m++){for(int n = 0; n < grid[0].size(); n++){ret = max(ret, h[m][n]);}}}
};

地图分析

https://leetcode.cn/problems/as-far-from-land-as-possible/

题目要求

在这里插入图片描述

题目解析

该题题目要求求海洋单元格距离陆地单元格的最大路径距离,本质还是多源BFS问题,这里如果将海洋单元格看作一个超级源点,正向BFS是比较复杂的,当搜索到了陆地,还需要把原来出发的海洋单元格标记一下距离,正难则反,可以从陆地出发,将陆地单元格添加到队列中,一层层地向外扩展,扩展一层标记一层的距离 只需要比上一层距离多1即可,这样是比正向BFS要简单很多的
 h[x][y] = h[a][b] + 1;

代码如下

class Solution {
public:int maxDistance(vector<vector<int>>& grid) {int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};queue<pair<int, int>> q;int ret = -1;    //如果陆地找不到海洋的话,直接返回vector<vector<int>> h(grid.size(), vector<int>(grid[0].size(), -1));  //-1表示格子未被访问过for(int i = 0; i < grid.size(); i++){for(int j = 0; j < grid[0].size(); j++){if(grid[i][j] == 1)  {h[i][j] = 0;q.push({i, j});}}}while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size() && h[x][y] == -1){h[x][y] = h[a][b] + 1;q.push({x, y});ret = max(ret, h[x][y]);    }}}return ret;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147017.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

故障诊断│GWO-DBN灰狼算法优化深度置信网络故障诊断

1.引言 随着人工智能技术的快速发展&#xff0c;深度学习已经成为解决复杂问题的热门方法之一。深度置信网络&#xff08;DBN&#xff09;作为深度学习中应用比较广泛的一种算法&#xff0c;被广泛应用于分类和回归预测等问题中。然而&#xff0c;DBN的训练过程通常需要大量的…

机器人速度雅可比矩阵(机器人动力学)

博途PLC矩阵求逆 矩阵求逆 博图SCL_博图矩阵运算-CSDN博客文章浏览阅读839次。本文介绍如何用C语言实现矩阵求逆的过程,详细解析了相关代码,适合线性代数和编程爱好者学习。https://rxxw-control.blog.csdn.net/article/details/122367883 1、二自由度平面关节机器人速度雅…

项目第十二弹:功能联调

项目第十二弹&#xff1a;功能联调 一、发布订阅功能测试1.生产者2.消费者3.演示4.持久化信息查看1.消息2.SQLite3数据库 二、持久化恢复测试1.代码2.gc3.演示 三、虚拟机和信道隔离测试1.责任划分2.如何测试3.生产者4.消费者5.演示 一、发布订阅功能测试 我们直接上TOPIC交换…

MySQL中的逻辑条件

逻辑条件组合两个比较条件的结果来产生一个基于这些条件的单个的结果&#xff0c;或者逆转一个单个条件的结果。当所有条件的结果为真时&#xff0c;返回行。 SQL的三个逻辑运算符是&#xff1a; AND、OR、NOT 可以在WHERE子句中用AND和OR运算符使用多个条件。 示例一&#…

惊爆!高通要收购英特尔,巨头也会被时代抛弃!

今天看到的外媒消息&#xff0c;高通要收购英特尔&#xff0c;看到消息的时候&#xff0c;其实&#xff0c;还是挺吃惊的。 高通是移动芯片的王者&#xff0c;英特尔是 PC 芯片的王者。当然了&#xff0c;英特尔这个可能需要再加上两个字&#xff1a;曾经的 PC 芯片王者。 其实…

植物大战僵尸【源代码分享+核心思路讲解】

植物大战僵尸已经正式完结&#xff0c;今天和大家分享一下&#xff0c;话不多说&#xff0c;直接上链接&#xff01;&#xff01;&#xff01;&#xff08;如果大家在运行这个游戏遇到了问题或者bug&#xff0c;那么请私我谢谢&#xff09; 大家写的时候可以参考一下我的代码思…

在VMware16中安装Windows 10:完整教程

在VMware中安装Windows 10&#xff1a;完整教程 1.安装环境准备2.创建虚拟机 1.安装环境准备 1.虚拟机: VMware-workstation-full-16.2.2-19200509 2.系统镜像:win10 2.创建虚拟机 1.自定义 2.下一步 3.稍后安装系统 3.默认下一步 4.虚拟机取名和选择存放路径(按需更改…

利士策分享,江西新余悲剧背后的深思:安全与责任的重构

利士策分享&#xff0c;江西新余悲剧背后的深思&#xff1a;安全与责任的重构 在这个信息瞬息万变的时代&#xff0c;每一次突发事件都能迅速触动社会的神经&#xff0c; 而江西新余近期发生的悲剧&#xff0c;更是让我们在悲痛之余&#xff0c;不得不深刻反思安全管理与社会…

AVL树与红黑树

目录 AVL树 AVL树节点的定义 AVL树的插入 AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 AVL树的验证 AVL树的性能 红黑树 红黑树的性质 红黑树节点的定义 红黑树结构 红黑树的插入操作 按照二叉搜索的树规则插入新节点 检测新节点插入后&#xff0c;红黑树的性…

升级你的HarmonyOS体验:一窥功能引导与拖拽交换的独家技巧

文章目录 前言项目目录结构开发流程主要步骤讲解关键配置Index.ets 页面讲解高光组件相关HeaderApp 总结 前言 在当今的移动应用开发领域&#xff0c;为了提供更加友好和直观的用户体验&#xff0c;开发者们通常会集成多种交互功能来增强应用的互动性和易用性。在这些功能中&a…

【机器学习】12-决策树1——概念、特征选择

机器学习10-决策树1 学习样本的特征&#xff0c;将样本划分到不同的类别&#xff08;分类问题&#xff09;或预测连续的数值&#xff08;回归问题&#xff09;。 选择特征&#xff0c;划分数据集&#xff0c;划分完成形成模型&#xff08;树结构&#xff09;&#xff0c;一个…

JavaSE——多线程基础

概述 现代操作系统&#xff08;Windows&#xff0c;macOS&#xff0c;Linux&#xff09;都可以执行多任务。多任务就是同时允许多个任务。例如&#xff1a;播放音乐的同时&#xff0c;浏览器可以进行文件下载&#xff0c;同时可以进行QQ消息的收发。 CPU执行代码都是一条一条顺…

Matlab R2018a怎么下载安装?Matlab R2018a保姆级详细安装教程

Matlab R2018a下载方法&#xff1a; Matlab R2018a安装教程&#xff1a; 1、右击下载好的压缩包&#xff0c;选择解压到Matlab R2018a 2、打开文件夹【R2018a_win64】&#xff0c;右击下面的setup.exe&#xff0c;选择【以管理员身份运行】 3、点击选择【使用文件安装密钥】&a…

IDEA连接数据库报错:Access denied for user ****

使用IDEA开发时&#xff0c;通过Databse连接数据库。多次连接报错&#xff1a;Access denied for user **** 如下所示&#xff1a; ​ ‍ ‍ ​ ‍ 花了不少时间排查&#xff0c;确认账号、密码&#xff0c;后面发现账号后多了个空格&#xff0c;而且不容易发现&#xf…

proteus仿真软件简体中文版网盘资源下载(附教程)

对于电子通信专业的小伙伴来说&#xff0c;今天文章的标题应该不会陌生。Proteus是一款具有广泛应用的仿真软件&#xff0c;它的功能非常强大&#xff0c;适用于所有单片机的仿真工作&#xff0c;能够从原理图、调试、到与电路的协同仿真一条龙全部搞定&#xff0c;受到所有用户…

交叉熵损失函数的使用

交叉熵损失函数 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;&#xff0c;也称为对数损失&#xff08;Log Loss&#xff09;&#xff0c;是机器学习和深度学习中常用的损失函数之一&#xff0c;尤其在分类问题中。它衡量的是模型预测的概率分布与真实标签的概率…

使用Properties

a.特点 i.它的Key-Value一般都是String-String类型的&#xff0c;可以用Map<String, String>表示。 ii.Java标准库提供Properties来表示一组“配置”。 iii.读写Properties时&#xff0c;使用getProperty()和setProperty()方法&#xff0c;不要调用继承自HashTabled的ge…

开始场景的制作+气泡特效的添加

3D场景或2D场景的切换 1.新建项目时选择3D项目或2D项目 2.如下图操作&#xff1a; 开始前的固有流程 按照如下步骤进行操作&#xff0c;于步骤3中更改Company Name等属性&#xff1a; 本案例分辨率可以如下设置&#xff0c;有能力者可根据需要自行调整&#xff1a; 场景制作…

轻掺杂漏极(LDD)技术

轻掺杂漏极&#xff08;LDD&#xff09;是一种低能量、低电流的注入工艺&#xff0c;通过该工艺在栅极附近形成浅结&#xff0c;以减少靠近漏极处的垂直电场。对于亚微米MOSFET来说&#xff0c;LDD是必需的&#xff0c;以便抑制热电子效应&#xff0c;这种效应会导致器件退化并…

Python进阶学习笔记(一)对象

1.对象模型 在面向对象理论中类和对象是不同的概念&#xff0c;而在python中类也是对象&#xff0c;叫做类型对象。 所以python中的类&#xff0c;实例对象&#xff0c;类型都是对象。 元类型&#xff1a; 在python中实例对象的类型为对应类型的对象&#xff0c;而类型的对象…