当前位置: 首页 > news >正文

【优选算法-多源 BFS】多源 BFS:解决多个起点的广度优先搜索

在这里插入图片描述

算法相关知识点可以通过点击以下链接进行学习一起加油!
BFS 解决最短路问题BFS解决拓扑排序

多源广度优先搜索(BFS)是一种在图算法中非常实用的技术,它通过同时从多个源点开始搜索,能够高效地解决一些复杂问题,特别是在处理多个起点的最短路径或传播问题时。与传统的单源 BFS 相比,多源 BFS 可以显著减少计算量和提高搜索效率。本文将探讨多源 BFS 的基本原理、应用场景及其与普通 BFS 的区别,并展示如何利用多源 BFS 来优化图算法,解决实际问题。

请添加图片描述

Alt

🌈个人主页:是店小二呀
🌈C/C++专栏:C语言\ C++
🌈初/高阶数据结构专栏: 初阶数据结构\ 高阶数据结构
🌈Linux专栏: Linux
🌈算法专栏:算法
🌈Mysql专栏:Mysql

🌈你可知:无人扶我青云志 我自踏雪至山巅 请添加图片描述

文章目录

    • 542. 01 矩阵
    • 1020. 飞地的数量
    • 1765. 地图中的最高点
    • 1162. 地图分析

本专题旨在解决 多源 BFS 问题,具体是利用 BFS 算法解决 边权为 1 的多源最短路径问题

在这里插入图片描述


542. 01 矩阵

题目】:542. 01 矩阵

在这里插入图片描述

算法思路

在这里插入图片描述

对于多源 BFS 问题,通常会为每个源点执行一次单源 BFS,但这种做法容易超时。我们可以采用 正难则反 的思路,将所有的 0 作为起点,1 作为终点,从而避免多次 BFS。

具体地,利用 超级起点 的思路,将所有的 0 的位置加入队列,开始一层层向外扩展。

在此过程中,为了避免重复遍历,我们不需要额外的 bool vis[][] 数组。通过将 dist[][] 初始化为 -1 来表示未访问过的节点,当一个节点被访问时,我们用 dist[x][y] = dist[a][b] + 1 来记录它的最短路径长度,相当于同时完成了遍历和层序遍历的功能。

代码实现

class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};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));queue<pair<int, int>> q;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.empty()){auto [a, b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a + dx[k], y = b + dy[k];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. 飞地的数量

题目】:1020. 飞地的数量

在这里插入图片描述

算法思路

在这里插入图片描述

这道题和‘130. 被围绕的区域’很相似,但不同的是,这里不需要修改原矩阵元素。我们可以借鉴‘130’的解法,首先处理边界元素,然后遍历矩阵,统计未被标记的区域数量。

这道题我们可以先处理边界情况,对边界上的1进行BFS,并标记为true。然后遍历矩阵,基于vis矩阵统计符合条件的数量。这两种解法都可以实现

原来[sz, step]是一起使用的,本道题while(sz--)其实是多余的,可以去掉。

代码实现

class Solution {
public:int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};bool vis[501][501];int m, n;int numEnclaves(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();queue<pair<int, int>> q;//1.处理边界情况,设置为truefor(int i = 0; i < m; i++){if(grid[i][0] == 1){q.push({i, 0});vis[i][0] = true;}if(grid[i][n - 1] == 1){q.push({i, n - 1});vis[i][n - 1] = true;}}for(int j = 0; j < n; j++){if(grid[0][j] == 1){q.push({0, j});vis[0][j] = true;}if(grid[m - 1][j] == 1){q.push({m - 1, j});vis[m - 1][j] = true;}}//2.进行BFSwhile(!q.empty()){auto[a, b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a + dx[k], y = b + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y]){q.push({x, y});vis[x][y] = true;}}}//3.遍历数组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;}
};

1765. 地图中的最高点

题目】:1765. 地图中的最高点

在这里插入图片描述

算法思路

在这里插入图片描述

如果直接求‘陆地到海洋的最大距离’比较困难,可以将问题转化为求‘海洋到陆地的最大距离’,因为两者的距离是对称的。通过利用‘连通块’和‘BFS’遍历,可以在题目要求的遍历次数内求解,简化了问题。

代码实现

class Solution {
public:int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {m = isWater.size(), n = isWater[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));//1.找到起始位置queue<pair<int, int>> q;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(isWater[i][j]){q.push({i, j});dist[i][j] = 0;}while(!q.empty()){auto[a, b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a + dx[k], y = b + dy[k];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. 地图分析

题目】:1162. 地图分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

算法思路

在这里插入图片描述

算法思路与‘1765. 地图中的最高点’类似,代码也大致相同。如果直接求‘海洋到陆地的最大距离’比较困难,可以将问题转化为求‘陆地到海洋的最大距离’,因为两者的距离是对称的。通过利用‘连通块’和‘BFS’遍历,可以在题目要求的遍历次数内求解,简化了问题。

代码实现

class Solution {
public:int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};int maxDistance(vector<vector<int>>& grid){m = grid.size(), n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));//1.找到起始位置queue<pair<int, int>> q;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(grid[i][j]){q.push({i, j});dist[i][j] = 0;}int ret = -1;while(!q.empty()){auto[a, b] = q.front();q.pop();for(int k = 0; k < 4; k++){int x = a + dx[k], y = b + dy[k];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.dtcms.com/a/294356.html

相关文章:

  • AI语境下创新教学模式应用示范与推广联盟成立| 南开大学携手和鲸,破解智能化时代教育难题
  • 只能在栈上创建对象
  • Linux网络-------1.socket编程基础---(UDP-socket)
  • 广州邮科万兆6光千兆48电工业级光纤交换机:三层功能如何重新定义网络智能化
  • Vue Scoped样式:当动态元素成为“无家可归“的孤儿
  • 2025年云南燃气经营企业从业人员考试题
  • Axios封装以及添加拦截器
  • UniApp X 网络请求避坑指南:从 JS 到 UTS 的 JSON 数据处理全解析
  • MCU驱动AD5231BRUZ_10K
  • GoLang学习笔记
  • Qt 菜单与工具栏设计:提升用户体验
  • stm32使用USB虚拟串口,因电脑缺少官方驱动而识别失败(全系列32单片机可用)
  • Git下载全攻略
  • 状压Dp和记忆化搜索
  • k8s怎么找deploy历史版本?
  • UDP通信是否需要使用bind,connect,send等函数
  • 如何高效合并音视频文件
  • iview+Tree 在数据中添加selected和expand属性默认展开后点不动问题
  • 【数据结构】——时间与空间复杂度深度解析
  • MATLAB近红外光谱分析:MATLAB编程+BP神经网络+SVM+随机森林+遗传算法+变量降维+卷积神经网络等
  • 云蝠智能 Voice Agent:重构企业语音交互,引领 AI 服务新范式
  • 《Spring Bean生命周期全景图解:从实例化到销毁》
  • 增强LLM最后隐藏层的意义与效果
  • 文本溢出时显示省略号,并在鼠标移入文本时显示 tooltip全内容
  • Taint Bug (污点漏洞):
  • 【bug】websocket协议不兼容导致的一个奇怪问题
  • 垃圾回收介绍
  • jenkins 入门指南:从安装到启动的完整教程
  • Selenium是解决了什么问题的技术?
  • web安全 | docker复杂环境下的内网打点