【算法】BFS算法解决多源最短路问题(C++)

文章目录

  • 前言
    • 那么什么是单源最短路 / 多源最短路呢?
    • 如何解决此类题?
      • 解法一
      • 解法二
        • 对于解法二,如何编写代码?
  • 算法题
    • 542.01矩阵
    • 1020.飞地的数量
    • 1765.地图中的最高点
    • 1162.地图分析

前言

此前我们对 单源最短路 问题进行的讲解:

使用bfs算法解决单源最短路问题


那么什么是单源最短路 / 多源最短路呢?

画图来说,单源最短路问题即为:

在这里插入图片描述

而对于多源最短路问题:

在这里插入图片描述


如何解决此类题?

自然是 利用BFS算法解决,下面提出解法:

解法一

在这里插入图片描述

解法二

在这里插入图片描述
当我们将所有的源点作为一个源点来进行解题时,问题又变成了单源最短路问题,而为什么可以认为这种解法是正确的呢?

  • 感性的理解 :对于上图的ABC三点,显然A点到目标点的距离更远,当我们将其作为一个点时,A点就会被直接排除,此时该特殊源点实际上就是最近的源点的合并。

对于解法二,如何编写代码?

我们对于 单源最短路 问题的bfs解法为:

  • 将起始点加入到队列中,再进行一层一层的扩展

自然,对于 多源最短路 的bfs解法为:

  • 将所有的起始点加入到队列中,再进行一层一层的扩展

在这里插入图片描述

算法题

542.01矩阵

在这里插入图片描述

思路

  • 题意分析:题目要求返回一个数组,该数组的每一位都是矩阵中当前位置到最近的0的距离。这个数组我们叫做dist数组,下面多道题都会用上,
  • 解法一 对每个位置都进行扩展
    在这里插入图片描述
  • 解法二: bfs + 正难则反 + dist数组
    • 正难则反:将思维逆转!我们以0作为起点,对矩阵进行扩容
    • dist数组:也是结果数组,开始初始化为-1,对于dist[i][j]:
      • dist[i][j] == -1:未被检索过
      • dist[i][j] != -1:该位置到0的最短距离
    1. 将矩阵的所有起始点0的位置加入矩阵
    2. 根据下图的思路,每次对队列中的元素进行扩展
      在这里插入图片描述

代码

class Solution {
public:int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0 ,0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int m = mat.size(), n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1)); // 将dist数组元素初始化为-1(未检索的状态)queue<pair<int, int>> q;// 正难则反:以矩阵中的0作为起点进行扩展// 将所有起始点入队for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j)if(mat[i][j] == 0){q.push({i, j});dist[i][j] = 0;}// 对队列中的元素进行拓展while(q.size()){auto [a, b] = q.front();    q.pop();for(int i = 0; i < 4; ++i){int x = dx[i] + a, y = dy[i] + b;if((x >= 0 && x < m) && (y >= 0 && y < n) && dist[x][y] == -1){dist[x][y] = dist[a][b] + 1;q.push({x, y});}}}return dist;}
};

1020.飞地的数量

在这里插入图片描述

思路

  • 题意分析:题目要求返回无法离开水域的陆地单元格个数,即在边界内且被水域完全包裹的单元格。
  • 解法 bfs + 正难则反
    • 正难则反:我们以四边的1为起点,向内扩展
    • 多源bfs:将四边的1作为起点入队,将相连接的陆地单元格标记
    • 最后遍历visited数组,统计结果

代码

class Solution {
public:int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};int numEnclaves(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();// 将visited数组元素初始化为0vector<vector<bool>> visited(m, vector<bool>(n, false));queue<pair<int, int>> q;// 正难则反:以边界的1为起始点,进行bfs// 1. 找到边界1,并扩展for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j)if(((i == 0 || i == m-1) || (j == 0 || j == n-1)) && grid[i][j] == 1){q.push({i, j});visited[i][j] = true;}// 2. 多源bfswhile(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 < m) && (y >= 0 && y < n) && !visited[x][y] && grid[x][y]){q.push({x, y});visited[x][y] = true;}}}// 3. 提取结果int ret = 0;for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j)if(!visited[i][j] && grid[i][j])++ret;return ret;}
};

1765.地图中的最高点

在这里插入图片描述

思路

  • 题意分析:题目给出一个矩阵,1为水域,0为陆地,要求我们自行安排陆地高度,使矩阵的最高高度最大(相邻单元格高度差 <= 1)
  • 解法 bfs + dist数组
  • 思路
    1. 首先创建dist数组,原理与第一题01矩阵一样,将矩阵中所有水域的位置在dist中初始化为0,并插入到队列中。
    2. 由于要求矩阵的最高高度最大,我们在设计高度时自然要将高度差都设为最大值,即1
    3. 随后进行多源bfs的操作,综上我们发现,这道题理清思路后,代码方面和“01矩阵”完全一致

代码

class Solution {
public:int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {// 思路同 “10矩阵”int m = isWater.size(), n = isWater[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> q;// 1.对水域进行扩展for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j)if(isWater[i][j] == 1) // 1是水域{q.push({i, j});dist[i][j] = 0;}// 2.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 < m) && (y >= 0 && y < n) && dist[x][y] == -1){q.push({x, y});dist[x][y] = dist[a][b] + 1;}}}return dist;}
};

1162.地图分析

在这里插入图片描述

思路

  • 题意分析:题目要求找到离陆地最远的海洋单元格的曼哈顿距离, 曼哈顿距离 简单解释为:
    在这里插入图片描述

  • 解法思路 bfs + 正难则反 + dist数组

    • 正难则反:题目要求找海洋到陆地的最大距离,我们以陆地单元格作为起始点,向内扩展
    • 同样的思路,我们首先遍历数组,将陆地单元格位置存入到队列中,并标记dist的位置
    • 后执行多源bfs的代码思路即可

代码

class Solution {
public:int dx[4] = {0, 0, -1, 1};int dy[4] = {-1, 1, 0, 0};int maxDistance(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();// 正难则反:以1为起点,向内扩展并标记vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> q;// 1. 根据单元格1向内扩展for(int i = 0; i < m; ++i)for(int j = 0; j < n; ++j)if(grid[i][j] == 1){q.push({i, j});dist[i][j] = 0;}// 2. 多源bfsint ret = -1; // 统计结果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 < m) && (y >= 0 && y < n) && dist[x][y] == -1){q.push({x, y});dist[x][y] = dist[a][b] + 1;ret = max(ret, dist[x][y]);}}}return ret;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年搭建幻兽帕鲁服务器价格多少?如何自建Palworld?

自建幻兽帕鲁服务器租用价格表&#xff0c;2024阿里云推出专属幻兽帕鲁Palworld游戏优惠服务器&#xff0c;配置分为4核16G和4核32G服务器&#xff0c;4核16G配置32.25元/1个月、3M带宽96.75元/1个月、8核32G配置10M带宽90.60元/1个月&#xff0c;8核32G配置3个月271.80元。ECS…

[ESP32 IDF] wifi 的应用

目录 背景知识 wifi的基本连接使用 WiFi篇—— WiFi两种模式文章中二、WiFi 的启动&#xff08;STA 及 AP 模式&#xff09; 输出现象 通过websocket控制LED 实践验证 实验现象 背景知识 WIFI是ESP32非常重要的一个功能&#xff0c;想要使用一下IDF的API实现将ESP32连…

Ubuntu中安装OpenSSL

Ubuntu中安装OpenSSL 参考&#xff1a;linux上安装Openssl步骤详解_linux安装openssl-CSDN博客 下载&#xff1a; https://www.openssl.org/source/openssl-3.0.1.tar.gz 解压&#xff1a; tar -xzvf xxxx.tar.gz 安装&#xff1a; cd openssl-3.0.12 ./config make -j3…

关于如何利用ChatGPT提高编程效率的

自从去年ChatGPT3.5推出以后&#xff0c;这一年时间在编程过程中我也在慢慢熟悉人工智能的使用&#xff0c;目前来看即使是免费的ChatGPT3.5对于编程效率的提升也是有很大帮助的&#xff0c;虽然在使用过程中确实出现了一些问题&#xff0c;本文记录下我的一些心得体会和用法。…

开发工具之GIT协同开发流程和微服务部署实践与总结

GIT协同开发流程和微服务部署的实践&#xff0c;并总结经验和教训。通过合理的GIT协同开发流程和良好的微服务部署策略&#xff0c;团队可以更高效地开发和部署软件。 ## 引言 在当今快节奏的软件开发环境中&#xff0c;采用合适的工具和流程对于实现高效协同开发和可靠部署至…

iOS 包含行间距计算富文本size

在一次开发过程中&#xff0c;发现带有行间距的富文本计算高度&#xff0c;会有不准确的情况&#xff0c;富文本内容明明很长&#xff0c;但是计算出的高度只有不到20像素&#xff0c;导致整个cell的高度计算异常。 需求上是文字固定宽度&#xff0c;最多显示3行&#xff0c;超…

FPGA高端项目:Xilinx Zynq7020系列FPGA多路视频拼接 工程解决方案 提供6套工程源码和技术支持

目录 1、前言版本更新说明给读者的一封信FPGA就业高端项目培训计划免责声明 2、相关方案推荐我已有的FPGA视频拼接叠加融合方案本方案在Xilinx Kintex7 系列FPGA上的应用本方案在Xilinx Artix7 系列FPGA上的应用 3、设计思路框架视频源选择ov5640 i2c配置及采集动态彩条多路视频…

精通Python第13篇—数据之光:Pyecharts旭日图的魔法舞台

文章目录 引言准备工作绘制基本旭日图调整颜色和样式添加交互功能定制标签和标签格式嵌套层级数据高级样式与自定义进阶主题&#xff1a;动态旭日图数据源扩展&#xff1a;外部JSON文件总结 引言 数据可视化在现代编程中扮演着重要的角色&#xff0c;而Pyecharts是Python中一个…

黑群晖使用SynologyDrive同步家庭和公司电脑文件

文章目录 前言一、黑群晖安装SynologyDrive服务二、樱花frp内网穿透2.1、创建一个隧道2.2、在群晖里面下载、安装、开启樱花frp 三、本地电脑安装SynologyDrive 前言 最近看b站学习视频&#xff0c;发现里面老师喜欢文件都是使用坚果云同步到云盘里面&#xff0c;以前我是瞧不…

OpenHarmony—仅允许在表达式中使用typeof运算符

规则&#xff1a;arkts-no-type-query 级别&#xff1a;错误 ArkTS仅支持在表达式中使用typeof运算符&#xff0c;不允许使用typeof作为类型。 TypeScript let n1 42; let s1 foo; console.log(typeof n1); // number console.log(typeof s1); // string let n2: typeof …

Nuget包缓存存放位置迁移

一、背景 默认情况下&#xff0c;NuGet会将项目中使用的包缓存到C盘&#xff0c;随着项目开发积累nuget包越来越多&#xff0c;这会逐渐挤占大量C盘空间&#xff0c;所以我们可以将nuget包缓存位置指定到其他盘中存放。 二、软件环境 win10、vs2022 三、查看当前缓存存放位…

亚信安慧AntDB打造开放创新的数据库生态

在当今信息化快速发展的时代背景下&#xff0c;亚信安慧AntDB作为一种新兴的DBMS&#xff0c;以其核心优势引起了行业内的广泛关注。它基于具有广泛全球影响力和繁荣社区支持的PostgreSQL(PG)内核&#xff0c;继承了PG的开放性与生态活力&#xff0c;同时在性能和稳定性方面进行…

【C++】引用、内联函数、auto关键字等

前言&#xff1a;在前面我们讲解了C入门基础的一些学习例如命名空间、缺省参数、函数重载等。今天我们将进一步的学习&#xff0c;跟着博主的脚步再次往前迈一步吧。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习…

万字长文扫盲JUC基础

文章源码地址 文章目录 JUC概述什么是JUC线程和进程的概念进程和线程线程的状态wait和sleep并发和并行管程monitor用户线程与守护线程 Lock接口复习Synchronizedsyschronized卖票案例多线程编程步骤 什么是Lock接口Lock接口的介绍Lock实现可重入锁实现卖票案例 线程间通信案例…

从云计算到物联网:虚拟化技术的演变与嵌入式系统的融合

文章目录 一、硬件性能提升&#xff1a;摩尔定律与嵌入式虚拟化二、CPU多核技术&#xff1a;为嵌入式虚拟化提供支持三、业务负载整合&#xff1a;嵌入式虚拟化的核心需求四、降低硬件成本&#xff1a;虚拟化技术的经济效益五、软件重用与移植&#xff1a;虚拟化技术的优势六、…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏4(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言源码制作系统简单绘制制作系统面板UI斧头素材代码控制工具栏操作制作石斧 完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇…

C#用DateTime.Now.ToString方法将日期格式化为指定格式

目录 一、DateTime.Now.ToString方法 二、实例 一、DateTime.Now.ToString方法 调用DateTime对象的ToString方法可以将当前DateTime对象的值转换为其等效的字符串表示形式&#xff0c;而且ToString方法提供了重载&#xff0c;可以在ToString方法中添加不同的参数&#xff0c;…

JAVA编程语言单词汇总

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发&#xff0c;并在 1995 年正式推出。后来 Sun 公司被 Oracle &#xff08;甲骨文&#xff09;公司收购&#xff0c;Java 也随之成为 Ora…

Android 基础技术——Bitmap

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 Bitmap Bitmap 内存如何计算 占用内存 宽 * 缩放比例 * 高 * 缩放比例 * 每个像素所占字节 缩放比例 设备dpi/图片所在目录的dpi Bitmap加载优化&#xff1f;不改变图片质量的情况下怎么优化&am…

【一竞技DOTA2】Blacklist战队官宣租借Palos参加ESL伯明翰预选赛

1、Blacklist战队官宣租借Palos参加ESL伯明翰站最终预选赛。Palos自2022年2月份以来一直效力于同为东南亚赛区的Execration战队&#xff0c;这次租借是替补前不久刚刚离队的Raven。 2、俄罗斯未来运动会最近官宣nouns战队因故退出。另外还有Neon、Nigma&#xff0c;Entity&…