【C++算法】BFS解决多源最短路问题相关经典算法题

1.01矩阵

既然本章是BFS解决多源最短路问题,也就是说有若干个起点,那我们就可以暴力一点,直接把多源最短路径问题转化成若干个单源最短路径问题,然后将每次的步数比较一下,取到最短的就是最短路径的结果,这个想法好写,但是在本章都会超时,所以我们换一个思路:把所有的源点当成一个超级源点(包含所有的源点),那么问题就变成了单一的单源最短路径问题,此时我们使用一次bfs就可以解决问题。但是如何将这个源点当作一个超级源点呢?在解决单源最短路问题,我们的做法是把起点加入到队列,然后一层一层的往外扩展,所以我们只需要一开始将所有的起点都加入到队列,然后一层一层往外扩展即可,我们直接看第一个思路:

代码我已经替大家试过了,会超时,所以我们来看第二种思路:

直接上代码:

class Solution {int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};
public:vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int m = mat.size();int n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));// dist[i][j] == -1,表示:没有被搜索过// dist[i][j] != -1,表示:最短距离// 利用dist来直接标记该位置是否已经被使用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()){// 此时我们不需要同时向外扩展// 因此不需要使用szauto [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){// 此时说明已经找到,直接修改dist的值即可dist[x][y] = dist[a][b] + 1;q.push({x, y});}}}return dist;}
};

2.飞地的数量

这道题目如果我们按照每次遍历数组每次遇到1就去bfs,肯定是会超时的,但是根据这个写法也有不超时的做法,我们遍历的时候,遇到1就去bfs,并将途中遇到1的位置标记一下,下一轮遇到1的时候,先dfs一下,如果这次dfs宽搜的时候遇到1,发现这个位置已经标记过,此时就不要bfs了,直接就是上次的结果,但是这样写需要两次dfs,并且dsf的代码还不一样,也比较麻烦,那我们来一个新思路:正难则反,我们可以从边上的 1 开始搜索,把与边上 1 相连的联通区域全部标记⼀下; 然后再遍历⼀遍矩阵,看看哪些位置的 1 没有被标记即可标记的时候,可以用「多源 bfs 」解决,bfs的逻辑和上一个题目基本差不多,直接上代码。

class Solution {int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};bool vis[501][501] = {false};
public:int numEnclaves(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();// 1. 把边上的 1 加⼊到队列中queue<pair<int,int>> q;// 遍历行for(int i = 0; i < n; i++){if(grid[0][i] == 1)q.push({0, i});if(grid[m - 1][i] == 1)q.push({m - 1, i});}// 遍历列for(int j = 0; j < m; j++){if(grid[j][0] == 1)q.push({j, 0});if(grid[j][n - 1] == 1)q.push({j, n - 1});}// 2. 多源bfswhile(q.size()){auto [a, b] = q.front();q.pop();vis[a][b] = true;for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y]){q.push({x, y});vis[x][y] = true;}}}// 统计结果int ret = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(grid[i][j] == 1 && !vis[i][j])ret++;return ret;       }
};

3.地图中的最高点

注意本题给的是结果矩阵,我们可以先来看看原始矩阵的样子

此时就一目了然了,我们直接创建一个height数组,将isWater中的水域依次向外扩展,直接转化成多源bfs的问题,并且我们发现它就是01矩阵的变型题,直接上代码了:

class Solution {int dx[4] = { 0, 0, 1, -1 };int dy[4] = { 1, -1, 0, 0 };
public:vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {int m = isWater.size();int n = isWater[0].size();// 数组不能初始化为0,因为数组中存在0 - 代表水域vector<vector<int>> height(m, vector<int>(n, -1));queue<pair<int, int>> q;// 把所有的源点加入到队列里面for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (isWater[i][j] == 1){height[i][j] = 0;q.push({ i,j });}// 多源bfswhile (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 < m && y >= 0 && y < n && height[x][y] == -1){height[x][y] = height[a][b] + 1;q.push({ x, y });}}}return height;}
};

4.地图分析

我们这个题目要求解海洋到陆地的最大距离,也可以求,但是海洋数量多蛮烦,正难则反,我们可以求陆地到海洋,将陆地作为超级源点依次向外扩展,随后创建一个dist数组,记录每次bfs的值保存在ist数组中即可解决,代码和上面的题目都相似,直接上代码:

class Solution
{int dx[4] = { 0, 0, 1, -1 };int dy[4] = { 1, -1, 0, 0 };
public:int maxDistance(vector<vector<int>>& grid){int m = grid.size(), n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> q;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (grid[i][j] == 1){dist[i][j] = 0;q.push({ i, j });}int 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){dist[x][y] = dist[a][b] + 1;q.push({ x, y });ret = max(ret, dist[x][y]);}}}return ret;}
};

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

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

相关文章

arcgis 10.6 工具栏操作error 001143 后台服务器抛出异常

arcgis 10.6 工具栏操作error 001143 后台服务器抛出异常 环境 win10arcgis 10.6 问题 执行定义投影要素转线出现 Error: 001143:后台服务器抛出异常&#xff08;差点重装10.6&#xff09; 如下图所示&#xff1a; 解决方法 通过在菜单工具条上单击地理处理 > 地理处…

设计模式使用(成本扣除)

前言 名词解释 基础名词 订单金额&#xff1a;用户下单时支付的金额&#xff0c;这个最好理解 产品分成&#xff1a;也就是跟其他人合做以后我方能分到的金额&#xff0c;举个例子&#xff0c;比如用户订单金额是 100 块&#xff0c;我方的分成是 80%&#xff0c;那么也就是…

OceanMind海睿思通过上海数交所数商认证,提供高质量数据治理和数据咨询服务

近日&#xff0c;中新赛克海睿思成功通过上海数据交易所的数商认证&#xff0c;获得上海数据交易所颁发的“数据产品开发服务商”、“数据治理服务商”和“数据咨询服务商”三大证书。 作为由深圳市创新投资集团有限公司投资控股的高新技术企业&#xff0c;国家级专精特新“小巨…

如何通过OpenHarmony的音频模块实现录音变速功能?

简介 OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;是由开放原子开源基金会孵化及运营的开源项目&#xff0c;是面向全场景、全连接、全智能时代的智能物联网操作系统。 多媒体子系统是OpenHarmony系统中的核心子系统&#xff0c;为系统提供了相机、…

Java入门基础学习笔记43——包

什么是包&#xff1f; 包是用来分门别类的管理各种不同程序的&#xff0c;类似文件夹&#xff0c;建包有利于程序的管理和维护。 建包的语法规则&#xff1a; package cn.ensource.javabean;public class Car() {} 在自己的程序中调用其他包下的程序的注意事项&#xff1a; 1…

动手学深度学习——层和块

1. 层 层是一个将输入数据转换为输出数据的神经网络组件。每个层都会对输入数据进行一定的操作&#xff0c;例如线性变换、非线性激活函数等&#xff0c;以产生输出数据。 torch.nn模块提供了各种预定义的层&#xff0c;如线性层、卷积层、池化层等&#xff0c; nn.Linear&a…

BLE学习笔记(0.0) —— 基础概念(0)

前言 &#xff08;1&#xff09;本章节主要是对BLE技术进行简单的介绍&#xff0c;熟悉蓝牙技术的发展过程&#xff0c;了解相关术语方便后续的学习。 &#xff08;2&#xff09;为了防止单篇博客太长以至于看不下去&#xff0c;因此我基础概念章节分为两篇来写。 &#xff08;…

Mysql教程(0):学习框架

1、Mysql简介 MySQL 是一个开放源代码的、免费的关系型数据库管理系统。在 Web 开发领域&#xff0c;MySQL 是最流行、使用最广泛的关系数据库。MySql 分为社区版和商业版&#xff0c;社区版完全免费&#xff0c;并且几乎能满足全部的使用场景。由于 MySQL 是开源的&#xff0…

1075: 求最小生成树(Prim算法)

解法&#xff1a; 总结起来&#xff0c;Prim算法的核心思想是从一个顶点开始&#xff0c;一步一步地选择与当前最小生成树相邻的且权值最小的边&#xff0c;直到覆盖所有的顶点&#xff0c;形成一个最小生成树。 #include<iostream> #include<vector> using names…

springboot基于Web前端技术的java养老院管理系统_utbl7

3.普通用户模块包括&#xff1a;普通会员的注册、养老院客房查询、养老院留言查询、预约老人基本信息登记、选择房间、用户缴费的功能。 4.数据信息能够及时进行动态更新&#xff0c;增删&#xff0c;用户搜素方便&#xff0c;使用户可以直接浏览相关信息&#xff0c;要考虑便于…

Vue3实战笔记(35)—集成炫酷的粒子特效

文章目录 前言一、vue3使用tsparticles二、使用步骤总结 前言 学习一个有趣炫酷的玩意开心一下。 tsparticles&#xff0c;可以方便的实现各种粒子特效。支持的语言框架也是相当的丰富. 官网&#xff1a;https://particles.js.org/ 一、vue3使用tsparticles 先来个vue3使用…

代码随想录训练营打卡第36天:动态规划解决子序列问题

1.300最长递增子序列 1.问题描述 找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。 2.问题转换 从nums[0...i]的最长的递增的子序列 3.解题思路 每一个位置的n…

C++多态详解

目录 一、多态的概念 二、多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写 4.例题理解&#xff08;超级重要&#xff0c;强烈建议做一下&#xff09; 5.C11 override和 final 6.重载、覆盖&#xff08;重写&#xff09;、隐藏&#xff08;重定义&#xff0…

零基础代码随想录【Day42】|| 1049. 最后一块石头的重量 II,494. 目标和,474.一和零

目录 DAY42 1049.最后一块石头的重量II 解题思路&代码 494.目标和 解题思路&代码 474.一和零 解题思路&代码 DAY42 1049.最后一块石头的重量II 力扣题目链接(opens new window) 题目难度&#xff1a;中等 有一堆石头&#xff0c;每块石头的重量都是正整…

(Qt) 默认QtWidget应用包含什么?

文章目录 ⭐前言⭐创建&#x1f6e0;️选择一个模板&#x1f6e0;️Location&#x1f6e0;️构建系统&#x1f6e0;️Details&#x1f6e0;️Translation&#x1f6e0;️构建套件(Kit)&#x1f6e0;️汇总 ⭐项目⚒️概要⚒️构建步骤⚒️清除步骤 ⭐Code&#x1f526;untitled…

【EasyX】快速入门——消息处理,音频

1.消息处理 我们先看看什么是消息 1.1.获取消息 想要获取消息,就必须学会getmessage函数 1.1.1.getmessage函数 有两个重载版本,它们的作用是一样的 参数filter可以筛选我们需要的消息类型 我们看看参数filter的取值 当然我们可以使用位运算组合这些值 例如,我们…

华为CE6851-48S6Q-HI升级设备版本及补丁

文章目录 升级前准备工作笔记本和交换机设备配置互联地址启用FTP设备访问FTP设备升级系统版本及补丁 升级前准备工作 使用MobaXterm远程工具连接设备&#xff0c;并作为FTP服务器准备升级所需的版本文件及补丁文件 笔记本和交换机设备配置互联地址 在交换机接口配置IP&#…

Facebook隐私保护:数据安全的前沿挑战

在数字化时代&#xff0c;随着社交媒体的普及和应用&#xff0c;个人数据的隐私保护问题日益受到关注。作为全球最大的社交平台之一&#xff0c;Facebook承载了数十亿用户的社交活动和信息交流&#xff0c;但与此同时&#xff0c;也面临着来自内外部的数据安全挑战。本文将深入…

AWS Elastic Beanstalk 监控可观测最佳实践

一、概述 Amazon Web Services (AWS) 包含一百多种服务&#xff0c;每项服务都针对一个功能领域。服务的多样性可让您灵活地管理 AWS 基础设施&#xff0c;然而&#xff0c;判断应使用哪些服务以及如何进行预配置可能会非常困难。借助 Elastic Beanstalk&#xff0c;可以在 AW…

AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(七):快启

前言: 汽车仪表是人们了解汽车状况的窗口,而仪表中的大部分信息都是以指示灯形式显示给驾驶者。仪表指示灯图案都较为抽象,对驾驶不熟悉的人在理解仪表指示灯含义方面存在不同程度的困难,尤其对于驾驶新手,如果对指示灯的含义不求甚解,有可能影响驾驶的安全性。即使是对…