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

算法训练之多源BFS


♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥

♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥

♥♥♥我们一起努力成为更好的自己~♥♥♥

♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥

♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥

✨✨✨✨✨✨ 个人主页✨✨✨✨✨✨

           前面我们已经介绍到许多使用BFS解决问题,今天这一篇博客我们来学习一下多源BFS,准备好了吗~我们发车去探索BFS的奥秘啦~🚗🚗🚗🚗🚗🚗

目录

什么是多源BFS?😜

01矩阵😝

飞地的数量😁

地图中的最高点😁

地图分析😀

什么是多源BFS?😜

        多源从这个名字上来看就是多个源头,我们这里把源头理解为起点~

形象比喻:

普通的BFS(单源BFS)

        想象一下,你在一个巨大的迷宫的中心点(一个起点),你的目标是找到出口。你探索迷宫的方式是:

    ①从你当前的位置(起点)开始。

    ②向你周围的四个方向(上、下、左、右)各迈出一步,探索这些相邻的格子。这些就是你“第一波”能到达的地方。

    ③然后从这“第一波”的每个格子,再分别向它们的四周探索,这就是“第二波”。

    ④如此一波一波地扩散出去,就像在水池中投入一颗石子,涟漪从中心一圈圈地荡开,直到碰到出口(目标)为止。

        这个过程就是 单源BFS,它只有一个起点


多源BFS

        现在,场景发生变化。想象同一个巨大的迷宫,但这次不是一个你,而是你和你的好几个朋友(比如3个人)同时在不同的位置,你们的任务还是找到出口,但这次你们可以协作。你们同时开始,从各自的位置出发,向四周探索。这个过程就是多源BFS!

    多源:指的就是有多个起点(你和你朋友们的位置)。

    BFS:还是一层层扩散的搜索算法

多源BFS如何工作?

它的核心思想非常巧妙:把多个起点都看作是“第0层”

    ①初始化:在开始时,不要只把一个起点放入队列,而是把你所有朋友的位置(所有起点)都放入队列,并标记为已访问。它们到自己的距离都是0。

    ②开始扩散:然后,像普通BFS一样,从队列中逐个取出位置进行探索。

    关键点:当从队列中取出一个点进行扩散时,你不需要关心这个点最初是来自哪个起点的。你们(所有起点)就像一个“超级团队”,团队的边缘同步向外推进。

        结果就是:整个迷宫被你们这个“超级团队”的涟漪共同覆盖,这个联合的涟漪圈会以最快的速度触碰到出口。

通过这个比喻相信大家对多源BFS有了更加深刻的理解,接下来使用表格总结一下:

特性单源BFS多源BFS
起点数量一个多个
初始化将一个起点入队将所有起点入队
核心思想从一个点开始一圈圈扩散从多个点开始,共同一圈圈扩散
解决问题从A点到B点的最短路径找到每个点离它最近的那个起点的最短距离
比喻一颗石子激起涟漪多处同时起火,蔓延整个森林

光说不练假把式,我们来看看几道题目~

01矩阵😝

01矩阵

我们从0开始出发,向周边扩散~

算法思路

①初始化

    创建距离矩阵,初始值-1(未访问)

    所有0的位置入队列,距离设为0

②BFS扩散

    从队列取出位置,向四个方向扩散

    遇到未访问位置:加入队列,并且更新距离:新距离 = 当前距离 + 1

③返回结果

    队列为空时,返回距离矩阵

代码实现

//01矩阵
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();//记录距离,同时初始化数据为-1,代表未访问vector<vector<int>> dist(m, vector<int>(n, -1));//创建坐标队列queue<pair<int, int>> q;//每一个格子到最近0的距离//1、把0当作起点——所有为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;//修改距离}}}//2、根据队列向周围扩散记录距离while (q.size()){auto [qx, qy] = q.front();q.pop();for (int i = 0; i < 4; i++){int cx = qx + dx[i], cy = qy + dy[i];if (cx >= 0 && cx < m && cy >= 0 && cy < n && dist[cx][cy] == -1){q.push({ cx,cy });dist[cx][cy] = dist[qx][qy] + 1;}}}//3、返回结果return dist;}
};

顺利通过~

飞地的数量😁

飞地的数量

算法思路

边界陆地入队

    遍历矩阵的四条边

    将所有边界上的陆地(1)加入队列

    标记这些位置为已访问

多源BFS扩散【标记联通块】

    从队列中取出位置

    向四个方向扩散寻找相邻陆地

    将找到的相邻陆地加入队列并标记

统计飞地数量

    遍历整个矩阵

    统计所有是陆地(1)但未被访问的位置

    这些就是无法到达边界的飞地

返回结果

代码实现

//飞地的数量
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();//同样大小数组——标记是否被访问vector<vector<bool>> vis(m, vector<bool>(n, false));//创建队列queue<pair<int, int>> q;//1、让所有边界"1"入队列,作为起点for (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 i = 0; i < n; i++){if (grid[0][i] == 1){q.push({ 0,i });vis[0][i] = true;}if (grid[m - 1][i] == 1){q.push({ m - 1,i });vis[m - 1][i] = true;}}//2、标记所有边界联通块为访问状态while (q.size()){auto [qx, qy] = q.front();q.pop();for (int i = 0; i < 4; i++){int cx = qx + dx[i], cy = qy + dy[i];if (cx >= 0 && cx < m && cy >= 0 && cy < n && grid[cx][cy] == 1 && vis[cx][cy] == false){q.push({ cx,cy });vis[cx][cy] = true;}}}//3、统计所有没有被访问过的1int count = 0;for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){if (grid[i][j] == 1 && vis[i][j] == false){count++;}}}//4、返回结果return count;}
};

顺利通过~

地图中的最高点😁

地图中的最高点

算法思路

初始化

    创建高度矩阵,初始值-1(未访问)

    遍历矩阵,找到所有水域:

        加入队列

        高度设为0

多源BFS扩散

    从队列取出位置

    向四个方向扩散:检查边界和是否未访问,新位置高度 = 当前位置高度 + 1,加入队列

返回结果

    当队列为空时,所有位置高度已确定

    返回高度矩阵

代码实现

//地图中的最高点
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){int m = isWater.size(), n = isWater[0].size();vector<vector<int>> height(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){q.push({ i,j });height[i][j] = 0;}}}//2、向周围扩散——bfswhile (q.size()){auto [qx, qy] = q.front();q.pop();for (int i = 0; i < 4; i++){int cx = qx + dx[i], cy = qy + dy[i];if (cx >= 0 && cx < m && cy >= 0 && cy < n && height[cx][cy] == -1){q.push({ cx,cy });height[cx][cy] = height[qx][qy] + 1;}}}//3、返回结果return height;}
};

顺利通过~

地图分析😀

地图分析

算法思路

陆地入队

    遍历整个网格,将所有陆地(1)加入队列,距离矩阵中陆地距离设为0

多源BFS扩散

    从队列取出位置,向四个方向扩散到海洋: 更新海洋单元格距离 = 当前距离 + 1;加入队列继续扩散; 实时更新最大距离ret

返回结果

    返回记录的最大距离ret

    如果ret未更新(全陆地或全海洋),返回-1

代码实现

//地图分析
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();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 (grid[i][j] == 1){q.push({ i,j });dist[i][j] = 0;}}}int ret = -1;//记录结果//2、陆地向周围扩散扩大距离while (q.size()){auto [qx, qy] = q.front();q.pop();for (int i = 0; i < 4; i++){int cx = qx + dx[i], cy = qy + dy[i];if (cx >= 0 && cx < m && cy >= 0 && cy < n && dist[cx][cy] == -1){q.push({ cx,cy });dist[cx][cy] = dist[qx][qy] + 1;ret = max(ret, dist[cx][cy]);//更新结果}}}//3、返回结果return ret;}
};

顺利通过~


♥♥♥本篇博客内容结束,期待与各位优秀程序员交流,有什么问题请私信♥♥♥

♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥

✨✨✨✨✨✨个人主页✨✨✨✨✨✨


http://www.dtcms.com/a/500045.html

相关文章:

  • 网站开发用什么语言比较流行网站建设未验收会计账务处理
  • openKylin 2.0版本学习入门
  • 如何用php数据库做网站搜狗收录提交
  • 人工智能三要素→ 数据 算力 算法
  • 做教育视频网站用什么平台好wordpress内网
  • 域名做好了怎么做网站内容网站搭建百家号
  • Spyder下载安装图文教程(附安装包,适合新手)
  • 南宁手机平台网网站建设龙岗建设工程交易中心官网
  • 网站移动端开发需要哪些技术ai代码生成器
  • 静态网页建站装饰画
  • 电商运营如何提升自身技能素质
  • iptables 防火墙详解与实用配置指南
  • 湖南网站建设加盟代理企业微营销网站
  • 可以大量免费发帖的网站wordpress存档显示文章所有内容
  • BPMN.js与LogicFlow流程设计器核心技术解析
  • python程序打包成win的exe应用(以OCR应用为例)
  • 建设营销型网站价格wordpress固定连接nginx
  • DRF:Django REST Framework框架介绍
  • 不备案 网站 盈利合肥做个网站多少钱
  • 做网站只用php不用html扬中网站建设哪家好
  • Linux内核idr数据结构使用
  • 3.3栈与队列的应用
  • 黑龙江网站开发公司宁波网站建设制作的公司
  • 《CopyOnWriteArrayList / CopyOnWriteArraySet 源码与“大对象复制”事故实录》
  • 做网站的品牌公司有哪些安康市110报警平台
  • 三水住房和城乡建设局的网站一键生成logo免费图
  • 自用EUBIU
  • 省住房城乡建设厅网站保险查询平台
  • 智能PDU在数据中心场景中的应用与解决方案
  • 网站登录界面图片用什么软件做深圳关键词优化报价