BFS 解决边权为1的最短路问题

文章目录

    • 边权为1的最短路问题
    • 1926. 迷宫中离入口最近的出口
      • 题目解析
      • 算法原理
      • 代码实现
    • 433. 最小基因变化
      • 题目解析
      • 算法原理
      • 代码实现
    • 127. 单词接龙
      • 题目解析
      • 算法原理
      • 代码实现
    • 675. 为高尔夫比赛砍树
      • 题目解析
      • 算法原理
      • 代码实现

边权为1的最短路问题

最短路问题:

比如说从D->K,找出最短的那条,其中每条路都是有权值,此篇主要讲解的边权为1的最短路问题

即边权都是一样的。

image-20240917202123546

解法就是从起点开始,做一次BFS:

  • 需要一个队列、一个哈希表(检测是否访问过)
  • 起点进入队列,然后哈希表标记
  • 弹出队头元素,将队头元素能去的位置,加入队列
  • 然后将该层依次元素弹出,弹出时继续加入能去的位置(哈希表检测一下)
  • 到终点就停止

BFS为什么能找出最短路径:

简单理解一下,假设有4条路,相当于4个人一起出发,每个人每次都向后移动一个单位(因为权值为1),最先到的那一个,就直接“跳出循环”了。

image-20240917203151230

如何找出最短路径:

拓展的层数,就是最短路的长度

1926. 迷宫中离入口最近的出口

题目链接:1926. 迷宫中离入口最近的出口

题目解析

题目给了我们两个数组:

  • 二维数组表示迷宫,+表示墙(不能走),.表示空格(可以走)
  • 一维数组:当前起始位置

每次只能往上下左右走一步,遇见墙不能走,让我们求最少走多少步,能走到迷宫(走到就行,不用走出去,没有出口就返回-1)。

矩阵大小为m*n

出口是矩阵的边界位置:x == 0 || x == m -1 || y == 0 || y == n -1

算法原理

每次走一步,找到最少步数,即可以理解为边权为1的最短路问题

  • 每次只能往上下左右走一步
  • 遇墙不走,第一次到边界就直接返回

代码实现

class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};bool vis[101][101];int m = 0;int n = 0;int nearestExit(vector<vector<char>>& maze, vector<int>& entrance){int ret = 0;m = maze.size();n = maze[0].size();//memset(vis, 0, sizeof(vis));queue<pair<int, int>> q;q.push({entrance[0], entrance[1]});vis[entrance[0]][entrance[1]] = true;while(q.size()){ret++;int sz = q.size();for(int i = 0; i < sz; i++){auto [x, y] = q.front();q.pop();for(int k = 0; k < 4; k++){int a = dx[k] + x;int b = dy[k] + y;if(a >= 0 && a < m && b >= 0 && b < n && maze[a][b] == '.' && !vis[a][b]){if(a == 0 || a == m -1 || b == 0 || b == n -1){return ret;}q.push({a, b});vis[a][b] = true;}}}}return -1;}
};

433. 最小基因变化

题目链接:433. 最小基因变化

题目解析

给我们2个基于序列(字符串)startend,再给我们一个基因库序列(vector<string>bank,它们都是由8个字符组成,每个字符都是ACGT其中之一

要我们找出从start 变为 end的最短次数,且每次变化,必须要在基因库能找到对应的。

算法原理

每次只能改变基于序列的一个字符,相当于中间可能会产生很多基因序列,然后才到目标序列。

将起始基于序列抽象成一个点,中间的序列抽象成路径,目标序列也是一个点,这样即转换成了求边权为1的最短路径问题

注意事项:

  • 用哈希表标记搜索过的字符串
  • 对元素字符串一位一位遍历,修改成ACGT其中一个,这样即可枚举出所以变化情况
  • 枚举出的字符串,符合基因库且为搜索过,加入队列
  • 基因库的字符串也丢入哈希表,即可快速判断

代码实现

class Solution {
public:int minMutation(string startGene, string endGene, vector<string>& bank){string s = "ACGT";unordered_set<string> hash(bank.begin(), bank.end());   //基因库unordered_set<string> vis;  //是否搜索过if(!hash.count(endGene)){return -1;}if(startGene == endGene){return 0;}queue<string> q;q.emplace(startGene);vis.emplace(startGene);int ret = 0;while(q.size()){ret++;int sz = q.size();while(sz--){string t = q.front();q.pop();for(int i = 0; i < 8; i++){string tmp = t; for(int j = 0; j < 4; j++){tmp[i] = s[j];if(hash.count(tmp) && !vis.count(tmp)){if(tmp == endGene){return ret;}q.emplace(tmp);vis.emplace(tmp);}}}}}return -1;}
};

127. 单词接龙

题目链接:127. 单词接龙

题目解析

这题意思和上面一题类似,就不多说了

唯一不一样的是,返回值为变化的单词数量

算法原理

思路也是和上一题一样

代码实现

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList){unordered_set<string> hash(wordList.begin(), wordList.end());unordered_set<string> vis;if(!hash.count(endWord)){return 0;}queue<string> q;q.emplace(beginWord);vis.emplace(beginWord);int ret = 1;    //记录单词个数while(q.size()){ret++;int sz = q.size();while(sz--){string t = q.front();q.pop();for(int i = 0; i < t.size(); i++){string tmp = t;for(char ch = 'a'; ch <= 'z'; ch++){tmp[i] = ch;if(hash.count(tmp) && !vis.count(tmp)){if(tmp == endWord){return ret;}q.emplace(tmp);vis.emplace(tmp);}}}}}return 0;}
};

675. 为高尔夫比赛砍树

题目链接:675. 为高尔夫比赛砍树

题目解析

给我们一个m*n的矩阵:

  • 0表示障碍,无法触碰
  • 1表示地面,可以行走
  • >1的表示有树,可以行走,数值表示树的高度

每次一个上下左右移动一步,如果遇到树,可以决定是否砍伐,砍完为1
砍伐树的顺序必须由低向高砍伐,比如说树的高度有3, 2, 6, 4, 5(树的高度都不同,切至少要砍到一棵树),砍伐的顺序必须是2, 3, 4, 5, 6

从下标[0, 0]出发,返回砍完所有树需要走的最小次数

算法原理

这里就求出每次要到达要砍位置的最短距离即可,即转换成了若干个迷宫问题了

这里还需要知道具体路径顺序,采用一个二维数组,记录位置,然后排一下序

image-20240917220748686

代码实现

class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m = 0;int n = 0;int cutOffTree(vector<vector<int>>& forest){m = forest.size();n = forest[0].size();vector<pair<int, int>> trees;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(forest[i][j] > 1)    trees.push_back({i, j});}}sort(trees.begin(), trees.end(),[&](const pair<int, int>& p1, const pair<int, int>& p2){return forest[p1.first][p1.second] < forest[p2.first][p2.second];});//砍树int bx = 0;int by = 0;int ret = 0;for(auto& [a, b] : trees){int step = bfs(forest, bx, by, a, b);if(step == -1)  return -1;ret += step;bx = a;by = b;}return ret;}bool vis[51][51];int bfs(vector<vector<int>>& f, int begin_x, int begin_y, int end_x, int end_y){if(begin_x == end_x && begin_y == end_y)    return 0;queue<pair<int, int>> q;memset(vis, 0, sizeof(vis));q.push({begin_x, begin_y});vis[begin_x][begin_y] = true;int step = 0;while(q.size()){step++;int sz = q.size();while(sz--){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 && y >= 0 && x < m && y < n && f[x][y] && !vis[x][y]){if(x == end_x && y == end_y){return step;}q.push({x, y});vis[x][y] = true;}}}}return -1;}
};

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

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

相关文章

Effective C++笔记之二十三:非void函数不写return

一.main函数 Qt Creator查看汇编的步骤如下 上图是g编译器下的汇编 eax就是main()函数的返回值 如果删掉return 0&#xff1b; 可以发现编译器还是把eax的值设为了0&#xff0c;由此可见&#xff0c;即使在main函数中不写return 0&#xff0c;编译器还是会默认添加个return 0。…

R语言统计分析——散点图2(散点图矩阵、高密度散点图)

参考资料&#xff1a;R语言实战【第2版】 1、散点图矩阵 pairs()函数可以创建基础的散点图矩阵。下面代码用于绘制一个散点图矩阵&#xff0c;包含mtcars数据集中的mpg、disp、drat和wt四个变量&#xff1a; pairs(~mpgdispdratwt,datamtcars,main"Basic Scatter Plot M…

太阳能光伏板航拍红外图像缺陷分类数据集

太阳能光伏板航拍红外图像缺陷分类数据集。 数据集共包含11种不同的缺陷分类&#xff0c; 总共20000张图片&#xff0c; 可用来做基于深度学习的缺陷分类 近红外&#xff0c;黑白图像&#xff0c;图示经过可视化处理。 数据集名称 太阳能光伏板缺陷分类数据集&#xff08;Sola…

三相可控整流电路 (三相半波,三相桥式)

目录 1. 三相半波整流电路 2. 三相桥式全控整流电路 三相可控整流电路利用三相交流电源&#xff0c;通过可控硅&#xff08;晶闸管&#xff09;将交流电整流为直流电。主要有两种常见类型&#xff1a;三相半波整流电路和三相桥式全控整流电路。 1. 三相半波整流电路 三相半波…

《沈阳体育学院学报》

《沈阳体育学院学报》创刊于1982年&#xff0c;是由沈阳体育学院主办&#xff0c;面向国内外公开发行的体育类学术期刊&#xff1b;国际标准刊号为ISSN 1004-0560&#xff0c;国内刊号为CN 21-1081/G8&#xff1b;双月刊&#xff0c;单月中旬出版。 《沈阳体育学院学报》是中文…

宝塔部署python项目

宝塔部署-python项目文章浏览阅读559次&#xff0c;点赞11次&#xff0c;收藏9次。在添加项目后&#xff0c;选择项目所在的路径&#xff0c;然后命令行启动主py文件。具体先看项目日志&#xff0c;根据日志在环境管理处下载包。首先下载项目需要的python版本。_宝塔部署python…

LabVIEW提高开发效率技巧----VI服务器和动态调用

VI服务器&#xff08;VI Server&#xff09;和动态调用是LabVIEW中的两个重要功能&#xff0c;可以有效提升程序的灵活性、模块化和可扩展性。通过这两者的结合&#xff0c;开发者可以在运行时动态加载和调用VI&#xff08;虚拟仪器&#xff09;&#xff0c;实现更为复杂的应用…

C++和OpenGL实现3D游戏编程【目录】

欢迎来到zhooyu的专栏。 个人主页&#xff1a;【zhooyu】 文章专栏&#xff1a;【OpenGL实现3D游戏编程】 贝塞尔曲面演示&#xff1a; 贝塞尔曲面演示zhooyu 本专栏内容&#xff1a; 我们从游戏的角度出发&#xff0c;用C去了解一下游戏中的功能都是怎么实现的。这一切还是要…

基于yolov8的无人机检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的无人机检测系统是一项前沿技术&#xff0c;结合了YOLOv8深度学习模型的强大目标检测能力与无人机的灵活性。YOLOv8作为YOLO系列的最新版本&#xff0c;在检测精度和速度上均有显著提升&#xff0c;特别适用于复杂和高动态的场景。 该系统通过捕获实…

论文笔记:基于LLM和多轮学习的漫画零样本角色识别与说话人预测

整理了ACM MM2024 Zero-Shot Character Identification and Speaker Prediction in Comics via Iterative Multimodal Fusion&#xff09;论文的阅读笔记 背景模型框架实现细节 实验数据集实验可视化消融实验 背景 最近读到一篇新文章&#xff0c;主要是做漫画中的零样本角色识…

pikachu下

CSRF(跨站请求伪造) CSRF(get) url变成了这样了&#xff0c;我们就可以新开个页面直接拿url去修改密码 http://pikachu-master/vul/csrf/csrfget/csrf_get_login.php?username1&password2&submitLogin CSRF(post&#xff09; 这里只是请求的方式不同&#xff0c;…

HC-SR04超声波传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 ultrasonic.h文件 ultrasonic.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 HC-SR04超声波传感器是通过发送和接收超声波&#xff0c;利用时间差和声音传播速度…

带你深入了解C语言指针(四)

目录 前言一、回调函数是什么&#xff1f;二、qsort使用1.什么是qsort2.qsort函数的语法解析3.回顾冒泡排序4.使用qsort函数排序整型数据4.1 思路分析4.2 完整代码&#xff1a;4.3 总体逻辑展现 5.使用qsort函数排序结构数据5.1 strcmp( )函数5.2 思路分析5.2.1 按名字比较5.2.…

力扣每日一题 公交站间的距离

环形公交路线上有 n 个站&#xff0c;按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离&#xff0c;distance[i] 表示编号为 i 的车站和编号为 (i 1) % n 的车站之间的距离。 环线上的公交车都可以按顺时针和逆时针的方向行驶。 返回乘客从出发点 start 到目…

C# 使用Socket通信,新建WinForm服务端、客户端程序

一、新建WinForm Socket服务端程序 注&#xff1a;rtbReceviceMsg为RichTextBox控件 服务端程序、界面 服务端代码 public partial class Form1 : Form {public Form1(){InitializeComponent();}public virtual void TriggerOnUpdateUI(string message){if (this.InvokeRequir…

Oracle发送邮件功能:配置自动化发信指南?

Oracle发送邮件服务设置方法&#xff1f;怎么用Oracle数据库发信&#xff1f; Oracle数据库作为企业级应用的核心&#xff0c;其内置的发送邮件功能为企业提供了强大的自动化工具。AokSend将详细介绍如何配置Oracle发送邮件功能&#xff0c;以实现自动化发信&#xff0c;从而提…

leetcode 2576.求出最多标记下标

2576.求出最多标记下标 题意&#xff1a; 解析&#xff1a; 数组长为 n n n&#xff0c;因为一次标记两个&#xff0c;所以数组中最多有 ⌊ n 2 ⌋ \lfloor \frac{n}{2}\rfloor ⌊2n​⌋ 对标记。 贪心的考虑&#xff0c;一个数 x 一定优先与满足 y ≥ 2 x y \ge 2x y≥2…

上海泗博EtherNet/IP转PROFIBUS DP网关EPS-320IP成都地铁项目应用案例

背景&#xff1a; 地铁&#xff0c;作为城市的活力脉搏&#xff0c;不仅是衔接城市生活的关键纽带&#xff0c;更是现代城市交通体系中不可或缺的核心组成部分。因此&#xff0c;确保地铁的稳定运行对任何一座城市都至关重要。 上海泗博自动化&#xff0c;作为与成都地铁项目合…

使用ENVI之辐射定标

将下载好的遥感影像导入遥感影像处理软件ENVI 5.6中 使用ENVI 5.6的Toolbox中的Radiometric Calibration工具 跳出的Date Input File界面中选中要进行辐射定标的文件选中 再在跳出的Radiometric Calibration界面中将Output Interleave改为BIL再点击Apply FLAASH Settings Soale…

【iOS】push和present的区别

【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中&#xff0c;我们经常性的会用到界面的一个切换的问题&#xff0c;这里我们需要理清…