当前位置: 首页 > 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.lryc.cn/news/597196.html

相关文章:

  • 【大模型文生图、文生音频实战Demo】基于Spring AI Alibaba和阿里百炼大模型实现文生图、文生视频
  • Android MediaCodec 的使用和源码实现分析
  • 2.1 为什么定义tensor数据结构?
  • 【有趣的跳跃一维数组问题】2022-7-27
  • 彻底掌握双列集合——Map接口以及实现类和常用API及其底层原理
  • 题解:P9468 [EGOI 2023] Candy / 糖果
  • 亚马逊云科技 上海AI研究院 突然解散 | AI早报
  • Taint Bug (污点漏洞):
  • GitHub 趋势日报 (2025年07月22日)
  • Docker 基础概念
  • 解决Node 17+版本与Metro、Webpack等兼容性问题(500)
  • 数据结构自学Day13 -- 快速排序--“分而治之”
  • ITIL 4:云计算与微服务对组织架构的影响
  • kotlin基础【1】
  • android studio(NewsApiDemo)100%kotlin
  • 【前端】当前主流的 CSS 预处理器语言Sass / SCSS、Less、Stylus
  • kotlin基础【2】
  • BaaS平台(Supabase)
  • 数据结构自学Day13 -- 快速排序--“前后指针法”
  • 《计算机网络》实验报告六 电子邮件
  • 数据结构(2)顺序表算法题
  • 【数据结构】二叉树的链式结构--用C语言实现
  • 数据结构系列之AVL树
  • Java冒泡排序的不同实现
  • Excel自动分列开票工具推荐
  • 耐达讯自动化EtherCAT转RS232:示波器连接的“开挂秘籍”
  • IDEA如何管理多个Java版本。
  • 图机器学习(16)——图数据与自然语言处理
  • 使用idea 将一个git分支的部分记录合并到git另一个分支
  • idea部署新项目时,用自定义的maven出现的问题解决