【算法】BFS 系列之 多源 BFS

news2024/9/21 1:22:43

【ps】本篇有 4 道 leetcode OJ。 

目录

一、算法简介

二、相关例题

1)01 矩阵

.1- 题目解析

.2- 代码编写

2)飞地的数量

.1- 题目解析

.2- 代码编写

3)地图中的最高点

.1- 题目解析

.2- 代码编写

4)地图分析

.1- 题目解析

.2- 代码编写


一、算法简介

        最短路问题是图论中一种经典的题型,包括单源最短路、多源最短路、边权为 1 的最短路等等。本篇主要讲述的是边权为 1 的多源最短路问题。

        简单来说,边权为 1 的单源最短路问题即为:求从单个起点到终点的最短路径距离,而边权为 1 的多源最短路问题即为:求从多个起点到终点的最短路径距离。

        对于多源的最短路问题,我们将多个相邻的起点看作是一个整体,进而简化成一个起点,将多源转化成单源并利用 BFS 来处理,具体的方式是,在用队列进行 BFS 时,将所有起点入队,然后一层一层向外扩展。

 ​

二、相关例题

1)01 矩阵

542. 01 矩阵

.1- 题目解析

        我们可以选择正难则反,不将 1 作为起点,而将 0 作为起点进行多源 BFS,去看 0 到达每个 1 的距离,从而得出最终的结果矩阵。

        可以先把所有的 0 都放在队列中,把它们当成一个整体,每次把当前队列里面的所有元素向外扩展一次。在遍历的时候还需要标记一下处理过的 1 ,这样才能做到只遍历整个矩阵一次,具体的方式是,在创建结果矩阵之初,将矩阵元素的值全都初始化为 -1。

.2- 代码编写

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(),n=mat[0].size();
        vector<vector<int>> dist(m,vector<int>(n,-1));
        //dist[i][j]==-1,表示没有被搜索过
        //dist[i][j]!=-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;
                }
            }
        }
        //BFS向外扩展
        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});
                }
            }
        }
        return dist;
    }
};

2)飞地的数量

1020. 飞地的数量

.1- 题目解析

        与上道题类似,我们也可以正难则反,从矩阵边上的 1 开始搜索,把与这些 1 相连的区域全部标记一下,然后再遍历一遍矩阵,统计哪些位置的 1 没有被标记即可,这些没有被标记的 1 就是不能到达边界的陆地。

.2- 代码编写

class Solution {
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
public:
    int numEnclaves(vector<vector<int>>& grid) {
        int m=grid.size(),n=grid[0].size();
        vector<vector<bool>> vis(m,vector<bool>(n));//标记某位置是否已经搜索过
        queue<pair<int,int>> q;
        //将矩阵边缘的 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)
                {
                    if(grid[i][j]==1)
                    {
                        q.push({i,j});
                        vis[i][j]=true;
                    }
                }
            }
        }
        //进行bfs向外扩展
        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 
                && grid[x][y]==1 && !vis[x][y])
                {
                    vis[x][y]=true;
                    q.push({x,y});
                }
            }
        }
        //统计结果
        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)地图中的最高点

1765. 地图中的最高点

.1- 题目解析

        本题类似于上文的《01矩阵》,也可以选择正难则反,以水域为起点,通过 BFS 向外扩展来安排结果矩阵中每个元素的高度,使得结果矩阵中的高度(元素)之和最大。

.2- 代码编写

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(),n=isWater[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(isWater[i][j])
                {
                    dist[i][j]=0;
                    q.push({i,j});
                }
        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});
                }
            }
        }
        return dist;
    }
};

4)地图分析

1162. 地图分析

.1- 题目解析

        本题类似于上文的《01矩阵》,曼哈顿距离其实就是最短距离,于是也可以选择正难则反,以陆地为起点,通过 BFS 向海洋去扩展。

 

.2- 代码编写

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])
                {
                    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.coloradmin.cn/o/2150728.html

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

相关文章

103.运行tomcat的Tomcatstartup.bat时,终端打印的中文显示为乱码

目录 原因 解决方法 原因 当运行Tomcat的Tomcatstartup.bat时&#xff0c;如果终端中文显示为乱码&#xff0c;这通常是因为Tomcat使用的日志输出编码与Windows命令行默认的编码不匹配。 解决方法 针对这一问题&#xff0c;你可以尝试以下步骤来解决&#…

【Spring】IocDI详解(6)

本系列共涉及4个框架&#xff1a;Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点&#xff0c;根据序号学习即可。 有什么不懂的都可以问我&#xff0c;看到消息会回复的&#xff0c;可能会不及时&#xff0c;请见谅&#xff01;&#xff01; 目录 本系列共…

深度图可视化显示(kitti)

文章目录 前言一、读取深度值与图像1、深度值读取2、图像读取 二、深度图可视化1、深度图可视化代码2、深度图可视化结果展示 三、深度图在图像上可视化1、可视化代码2、可视化坐标显示 四、完整代码 前言 kitti数据是一个通用数据&#xff0c;有关kitti的深度图像内容我已有博…

扣子智能体实战:一键生成公众号图文,AI时代文盲也能写公众号,赚钱秘籍

文章目录 一&#xff0c;需求简述二&#xff0c;智能体制作1&#xff0c;智能体人设和技能2&#xff0c;流程开发2.1 设置开始节点2.2 增加一个生成标题的大模型节点2.3 增加一个代码节点 2.4 增加一个插件节点用以生成文章配图2.4 增加一个大模型节点-根据标题和思路生成文章大…

Excel--WPS 函数与公式技巧(轻松搞定各类排名)

一、直接按成绩或数值的排序&#xff08;rank函数轻松搞定&#xff09; 以上函数非常简单&#xff0c;记住两点&#xff1a; 1.rank排名同分作为同一名次&#xff0c;后面的名次需要占位&#xff0c;如&#xff0c;以上两个70分&#xff0c;同为第8名&#xff0c;那么第9名将被…

Shader 中的光源

1、Shader 开发中常用的光源属性 Unity当中一共支持四种光源类型&#xff1a; 平行光&#xff08;Directional&#xff09;点光源&#xff08;Point&#xff09;聚光灯&#xff08;Spot&#xff09;面光源&#xff08;Area&#xff09;— 面光源仅在烘焙时有用 不管光源类型到…

可视化工具箱-Visualization Toolkit(VTK)

一、Visualization Toolkit&#xff08;VTK&#xff09;简概 可视化工具箱&#xff08;VTK&#xff09;&#xff0c;是一个用于3D计算机图形、图像处理和科学可视化的开源软件系统&#xff0c;其包含C类库和Tcl/Tk、Java与python的解释型接口层。VTK支持各种可视化算法&#xf…

软设9.20

1 已知一个文件中出现的各字符及其对应的频率如下表所示。若采用定长编码&#xff0c;则该文件中字符的码长应为()。若采用Hufman编码&#xff0c;则字符序列“face”的编码应为()。 1.&#xff08;&#xff09; A.2 B.3 C.4 D.5 2.&#xff08;&#xff09; A.110001001101…

小程序构建npm失败

小程序构建npm失败 项目工程结构说明解决方法引入依赖导致的其他问题 今天在初始化后的小程序中引入TDesign组件库&#xff0c;构建npm时报错。 项目工程结构说明 初始化后的项目中&#xff0c;包含miniprogram文件夹和一些项目配置文件&#xff0c;在project.config.json文件中…

VS运行程序时报错--无法定位程序输入点

发现问题&#xff1a; VS 在运行程序时&#xff0c;报错&#xff1a; 找到原因&#xff1a; 因为我在替换动态库的时候&#xff0c;只替换了lib库&#xff0c;没有替换运行目录下的dll库&#xff0c;运行时候的dll与程序中的lib库不对应。 替换库后就能解决这个问题。

秋意渐浓,温暖筹备——铁路职工御寒劳保鞋,寒冬无阻!

随着秋意渐浓&#xff0c;气温逐渐走低&#xff0c;冬日的寒风已在不远处蓄势待发。对于坚守在铁路一线的工友们来说&#xff0c;这不仅是季节的变换&#xff0c;更是工作装备升级换代的信号。意味着需要更加注重防寒保暖&#xff0c;以确保在寒冷的天气中能够安全、高效地工作…

前端大数据渲染:虚拟列表、触底加载与分堆渲染方案

前言 针对表格展示数据&#xff0c;用户提出要求前端在表格下面有一展示多少条数据的选项&#xff0c;如果要求一次性展示10000条数据&#xff0c;如果直接染会造成页面的卡顿&#xff0c;渲染速度下降&#xff0c;内容展示慢,如果有操作&#xff0c;操作会卡顿 下面总结常见…

工程师 - PFM介绍

在电子电路设计中&#xff0c;PFM&#xff08;Pulse Frequency Modulation&#xff0c;脉冲频率调制&#xff09;是一种调制技术&#xff0c;其主要特点是在负载变化时调整脉冲的频率&#xff0c;而保持脉冲的宽度&#xff08;时间长度&#xff09;相对恒定。与PWM&#xff08;…

lambda 自调用递归

从前序与中序遍历序列构造二叉树 官方解析实在是记不住&#xff0c;翻别人的题解发现了一个有意思的写法 class Solution { public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {auto dfs [](auto&& dfs, auto&&…

深度学习-图像处理篇1.1-1.2神经网络

1.1卷积神经网络基础 卷积层 对彩色RGB图像进行卷积 1.卷积核的通道数与输入特征层的通道数相同 2.卷积输出的特征矩阵通道数与卷积核个数相同 池化层 池化中一般池化核大小和步长大小一样 思考 加上偏移量bias该如何计算? 卷积计算时加上偏移量即可 加上激活函数该如何计…

Nomad Web服务终于成熟了!

大家好&#xff0c;才是真的好。 9月份HCL Notes/Domino相关产品发布的还真不少&#xff0c;前脚刚发布了HCL Notes Domino 14.5 EA1&#xff0c;后脚就迎来了Notes Domino 14.0FP2IF1&#xff0c;还有Nomad 1.0.13版本。 在我的记忆中&#xff0c;他们不喜欢数字13&#xff…

分布式消息中间件kafka

文章目录 什么是kafka?整体架构 kafka核心概念1. 生产者 (Producer)2. 消费者 (Consumer)3. 主题 (Topic)4. 分区 (Partition)5. 经纪人 (Broker)6. 复制 (Replication)7. 消费者组 (Consumer Group)8. 日志段 (Log Segment) 主要功能1. 高吞吐量2. 可靠的消息传递3. 发布/订阅…

打印菱形(图像打印)

//打印菱形 // ---* // *** // ***** // ******* // ***** // *** // * //一共需要line行&#xff0c;分成两边&#xff0c;上半部分需要line/21行 //下半部分需要line/2行 #include<stdio.h> #define L 11 //行 #define R 11 //列 int main() {int …

十三 系统架构设计(考点篇)试题

A 对&#xff0c;B对&#xff0c;C好像是分布式中间件吧&#xff0c;D对。选C 第一题&#xff0c;感觉肯定有交互支持&#xff0c;选B;第二B。实际答案&#xff1a;D和B。 在一个分布式系统中&#xff0c;中间件通常提供两种不同类型的支持&#xff1a; &#xff08;1&#xff…

【读书笔记-《30天自制操作系统》-23】Day24

本篇内容依然比较简单&#xff0c;主要是优化窗口功能以及开发定时器应用程序。首先是优化窗口的切换功能&#xff0c;实现通过键盘和鼠标切换窗口&#xff0c;然后是实现通过鼠标关闭窗口。接着实现不同窗口输入状态的切换&#xff0c;最后是实现定时器的API与应用程序。 1.…