BFS算法求迷宫的最短路径

2023-05-16

        BFS(Breadth-First Search)算法的具体实现就是:通过不断取得某个状态能够达到的所有状态并将其加入队列尾, 并且由于队列本身的特性先加入队列的状态总是先得到处理,这样就可以总是先将需要转移次数更少的状态进行处理。换句话说就是总是取得了这个状态的树中更接近根部的节点,又或者是总是让搜索树的广度得到尽可能增加。拿一个例子来说,有一个如图所示的迷宫,'#' 为墙壁,'.' 为道路,'S' 为起点,'G' 为终点,需要我们找出从起点到达终点的最短路径。

10 10  //地图的长和宽
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

在这个问题中,找到从起点到终点的最短路径其实就是一个建立队列的过程:

1.从起点开始,将其加入队列,设置距离为0;

2.从队列首端取出位置,将从这个位置能够到达的位置加入队列,并且让这些位置的距离为上一个位置的距离加上1;

3.一轮探索至无法继续向队列中添加元素,即当前所在点的四周情况全部考虑完成后,循环第二步,直到将终点添加到队列中。说明此时已经找到了路径;

#include <cstdio>
#include <queue>
using namespace std;

const int INF = 100000000;
typedef pair<int, int> P;
char maze[101][101];
int n, m;
int sx, sy, gx, gy;
int d[101][101];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};  //四个方向

int BFS(){
    queue<P> que;
    for(int i = 0; i < n; i++)
        for(int j = 0; j <m; j++)
            d[i][j] = INF;
    que.push(P(sx, sy));
    d[sx][sy] = 0;
    while(que.size()){
        P p = que.front();
        que.pop();
        if(p.first == gx && p.second == gy) break;
        for(int i = 0; i < 4; i++){
            int nx = p.first + dx[i], ny = p.second + dy[i];
            if(nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] != '#' && d[nx][ny] == INF){
                que.push(P(nx, ny));
                d[nx][ny] = d[p.first][p.second] + 1;
            }
        }
    }
    return d[gx][gy];
}

int main()
{
    scanf("%d %d", &n, &m);
    getchar();
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            scanf("%c", &maze[i][j]);
        }
        getchar();
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(maze[i][j] == 'S'){
                sx = i;
                sy = j;
            }
            else if(maze[i][j] == 'G'){
                gx = i;
                gy = j;
            }
        }
    }
    printf("%d\n", BFS());
    return 0;
}

        这个过程中,每次处理的位置所对应的距离是严格递增的,即在数组 d[][] 中可以看到一条数值为1、2、3、4、5...的通路,因此一旦找到终点,当时的距离就是最短距离,该距离被记录在 d[gx][gy] 中。搜索可移动到的位置所使用的判断条件中不仅仅是不碰墙壁、不超过边界,还有一个就是没有到达过,体现在 d[nx][ny] 的数值没有被修改过,因为如果已经到达了这个位置,这说明已经有更短的路径到达这个位置,这次到达这个位置的路径是更差的,可以不予考虑了。

扩展一道 POJ-3984 迷宫问题

题目链接:https://cn.vjudge.net/problem/POJ-3984

分析:这道题因为需要输出最短路径的坐标信息,所以我使用了一个数组将路径上每个点的前一个点用数组保存了起来。

代码:

#include <cstdio>
#include <queue>
using namespace std;

const int INF = 100000;
typedef pair<int, int> P;
int maze[5][5], d[5][5];
P father[5][5];  //记录上一个节点信息
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};  //四个方向

void BFS(){
    queue<P> que;
    for(int i = 0; i < 5; i++){
        for(int j = 0; j < 5; j++){
            d[i][j] = INF;
            father[i][j].first = -1;
            father[i][j].second = -1;
        }
    }
    que.push(P(4, 4));
    d[4][4] = 0;
    while(que.size()){
        P p = que.front();
        que.pop();
        if(p.first == 0 && p.second == 0) break;
        for(int i = 0; i < 4; i++){
            int nx = p.first + dx[i], ny = p.second + dy[i];
            if(nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && maze[nx][ny] != 1 && d[nx][ny] == INF){
                que.push(P(nx, ny));
                father[nx][ny].first = p.first;
                father[nx][ny].second = p.second;
                d[nx][ny] = d[p.first][p.second] + 1;
            }
        }
    }
    return;
}

int main()
{
    char c;
    for(int i = 0; i < 5; i++)
        for(int j = 0; j < 5; j++)
            scanf("%d", &maze[i][j]);
    BFS();
    int i = 0, j = 0;
    while(i != -1 && j != -1){
        printf("(%d, %d)\n", i, j);
        int tmp = i;  //有坑,必须先保存了i的值再做修改
        i = father[i][j].first;
        j = father[tmp][j].second;
    }
    return 0;
}

上下左右四种情况的判断 用数组加一个for循环 可以说是很神奇了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BFS算法求迷宫的最短路径 的相关文章

  • 如何在ubuntu22.04版本上安装libssl1.1?

    直接使用sudo apt get install会提示找不到软件包输入一下命令即可 xff1a echo 34 deb http security ubuntu com ubuntu focal security main 34 sudo
  • vue2学习总结一

    1 vue介绍 Vue是一套用于构建用户界面 xff08 数据 gt 界面 xff09 的渐进式 xff08 简单应用 xff08 一个轻量小巧的核心库 xff09 gt 复杂应用 xff08 可以引入各种各样的Vue插件 xff09 xf
  • c++判断字符串是否为回文

    回文是指正读反读均相同的字符序列 如 34 abba 34 和 abdba 均是回文 xff0c 但 34 good 34 不是回文 Solution1 使用reverse 函数将字符串反转 xff0c 与原字符串比较 xff0c 若相同
  • 多车调度问题(大疆Robot Master)——ROS键盘控制失灵,小车无法收敛定位,路径规划出错

    问题1 ROS键盘控制小车失灵 具体就是 xff1a 用键盘左右转小车 xff0c 速度贼快 xff0c 而且方向不正确 xff0c 检查发现是控制模块失灵 xff0c 有可能是内部测量元件 xff08 陀螺仪等 xff09 烧了 xff0
  • 浏览器跨域-原因及解决方案

    1 浏览器跨域 如何判断一个浏览器的请求是否跨域 xff1f 在A地址 xff08 发起请求的页面地址 xff09 向B地址 xff08 要请求的目标页面地址 xff09 发起请求时 xff0c 如果A地址和B地址在 xff1a 协议 域名
  • 使用moment.js时设置中文无效

    背景 xff1a 使用 script 标签 xff0c 在 html 页面中引入了 moment js xff0c 使用时发现页面中 moment js 相关的文字显示的是英文 xff08 eg xff1a 3 days ago xff09
  • virtual stdio 2017 问题

    严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8020 无法找到 Visual Studio 2010 的生成工具 平台工具集 61 v100 若要使用 v100 生成工具进行生成 xff0c 请安装 Visual Stud
  • 中国天气网天气api接口 天气预报调用方法 2020

    说明 百度了很久没有找到免费的天气 API 不是收费就是接口打不开了 最后终于找到了天气api https www tianqiapi com 可免费使用 最重要的是天气数据和中国天气网一致 城市编号也是用的天气网的 这样就方便多了 体验了
  • [路由][教程]OpenWrt通过LAN连接上级路由做交换机+无线功能教程

    1 前言 上级路由为ikuai软路由 xff0c 数据处理交给软路由来做 xff0c OpenWrt运行在路由器上 xff0c 通过LAN连接上级路由从而只做WIFI接收发送功能 此教程只能将LAN作为交换机使用 xff0c WAN口不行
  • [路由][教程]OpenWrt设置为交换机+无线功能教程

    1 前言 上级路由为ikuai软路由 xff0c 数据处理交给软路由来做 xff0c OpenWrt运行在路由器上 xff0c 通过LAN连接上级路由从而只做WIFI接收发送功能 2 需求 路由的LAN和WAN全部作为交换机使用无线WIFI
  • CV学习笔记-特征提取

    特征提取 1 概述 图像中常见的特征有边缘 角 区域等 通过各属性间的关系 xff0c 改变原有的特征空间 xff0c 例如组合不同的属性得到新的属性 xff0c 这样的处理叫做特征提取 注意特征选择是从原始的特征数据集中选择出子集 xff
  • CV学习笔记-深度学习

    深度学习 1 神经网络 1 概述 引例 xff1a 生物神经网络作用机理 生物神经网络的基本工作原理 xff1a 一个神经元的输入端有多个树突 xff0c 主要是用来接收输入信息的 输入信息经过突触处理 xff0c 将输入的信 息累加 xf
  • Mybatis-Plus条件构造器笔记

    Mybatis Plus条件构造器笔记 Mybatis Plus官方文档 xff1a https baomidou com pages 10c804 本文主要讨论Mybatis Plus条件构造器的区别和用法 QueryWrapper Up
  • 日常刷题 (0)

    牛客刷题 1 即使不进行强制类型转换 xff0c 在进行指针赋值运算时 xff0c 指针变量的基类型也可以不同 xff1f 答 xff1a 错 xff0c 指针变量的赋值只能赋予地址 xff0c 决不能赋予任何其它数据 xff0c 否则将引
  • coursera C程序进阶 第二周 #6

    题目 xff1a 流感传染 有一批易感人群住在网格状的宿舍区内 xff0c 宿舍区为n n的矩阵 xff0c 每个格点为一个房间 xff0c 房间里可能住人 xff0c 也可能空着 在第一天 xff0c 有些房间里的人得了流感 xff0c
  • 大数据学习路线图(旧)

    一 入门准备 1 linux操作基础 1 Linux的介绍 xff0c Linux的安装 xff1a VMware Workstation虚拟软件安装过程 CentOS虚拟机安装过程 2 Linux的常用命令 xff1a 常用命令的介绍 常
  • Linux网络编程:状态机

    Linux网络编程 xff1a 状态机 状态机基本概念介绍状态机的特征状态机的要素注意 xff01 为什么在网络编程中需要状态机 xff1f 状态机基本概念介绍 首先我们简单的介绍一下状态机的基本概念 有限状态机是一种用来进行对象行为建模的
  • Ubuntu 20.04 安装 cuda9.0不成功如何解决

    cuda9 0需要低版本gcc才能兼容 xff0c 试了很多教程 xff0c 最终参考以下链接安装成功 xff0c 粗略记录一下 xff0c 免得下次又采坑 1 安装低版本gcc xff1a gcc 5 4 0 参考以下链接 xff1a 不
  • (八)linux中断实现

    目录 一 linux中断的实现二 中断号三 中断的标志四 中断源对应的中断服务程序五 中断服务程序与原子上下文六 等待队列七 附录 一 linux中断的实现 span class token macro property span clas
  • i3wm 屏幕配置踩坑

    i3wm 屏幕配置踩坑 前言踩坑 前言 自从18 19年开始正式使用linux作为我的开发系统就一直没有换回windows 从一开始的 ubuntu 到后来的manjaro 感觉越来越有意思可玩性很高 至于我我什么不换回windows 原因

随机推荐

  • 这个Python库太强了,竟然能把图片,视频无损清晰放大!

    这几天在逛GitHub的时候发现了一个非常牛逼的库 xff0c 竟然有逆天的功能 xff0c 一个用Python做的库 xff0c 利用机器学习算法把图片无损的放大很多倍 这个库叫video2x xff0c 目前收获1500颗星 xff0c
  • 字符串和枚举的互相转化

    字符串和枚举的互相转化 字符串转枚举枚举转字符串总结 字符串转枚举 提示 xff1a 关键代码Enum Parse 代码如下 xff08 示例 xff09 xff1a string str span class token operator
  • CentOS7 安装mysql(YUM源方式)

    CentOS7 安装mysql xff08 YUM源方式 xff09 1 下载mysql源安装包 wget http dev mysql com get mysql57 community release el7 8 noarch rpm
  • Linux(5)---Linux中nano命令

    nano是一个字符终端的文本编辑器 xff0c 有点像DOS下的editor程序 它比vi vim要简单得多 xff0c 比较适合Linux初学者使用 某些Linux发行版的默认编辑器就是nano nano命令可以打开指定文件进行编辑 xf
  • Centos7安装配置桌面环境xfce

    1 centos最小化安装之后由于没有桌面环境 xff0c gnome太大 xff0c 所以找一个小的桌面环境用于一些不方便命令行的操作 2 首先是连接到网络 xff08 不详细展开了 xff09 3 安装桌面环境 yum groupins
  • 利用RSA+AES 前后端对数据进行加密处理 -- 整体思路

    利用RSA 43 AES 前后端对数据进行加密处理 整体思路 前言RSA加密算法RSA简介RSA缺点 AES加密算法AES简介AES缺点 RSA 43 AES 整体流程 前言 目前项目中需要对接口中的一些参数进行加密处理 xff0c 考虑了
  • centos7安装FreeSwitch,以及设置Freeswitch开机自启

    一 下载指定版本的freeswitch cd usr local src git clone branch v1 10 7 https github com signalwire freeswitch git 也可以下载1 10 7的压缩包
  • [iOS] TableViewCell 自适应高度

    说明 TableViewCell 几乎是必用控件 xff0c 使用 TableViewCell 免不了计算其 cell 高度 xff0c 网上也有非常多关于 TableViewCell 高度自适应的文章 xff0c 自己也尝试总结了计算ce
  • Tmux 使用教程

    转载自Tmux 使用教程 作者 xff1a 阮一峰 URL xff1a http www ruanyifeng com blog 2019 10 tmux html Tmux 1 Tmux 是什么 xff1f 1 1 会话与进程1 2 Tm
  • MacOS 下 VScode 编译运行 C/C++ (ACM向)简单粗暴

    VSCode 的下载 安装 在 VSCode 官网 点击 Download for Mac 开始下载 xff0c 之后双击下载完成的文件等待一会就安装好了 必备插件安装 VSCode 启动后 xff0c 点击左侧最下的方块形按钮 xff08
  • 写在2019年ACM-ICPC亚洲区域赛宁夏站之后——一只菜鸡的ACM生涯

    写在2019年ACM ICPC亚洲区域赛宁夏站之后 一只菜鸡的ACM生涯 一晃时间就过去了 xff0c 接触ACM也将近一年半的时间 在这段时间里 xff0c 有过找不出来bug的难受体验 xff0c 也有过茅塞顿开的兴奋激动 xff1b
  • win10下安装Anaconda3后cmd中运行“conda”命令显示“‘conda’不是内部或外部命令,也不是可运行的程序”的解决方法

    找到安装目录 Anaconda3 xff0c 例如我的是 C Users zuoyu Anaconda3 xff1b 将 Anaconda3 Anaconda3 Scripts Anaconda3 Library bin 三个目录添加到系统
  • VS Code中使用Code Runner运行Python代码时中文乱码问题解决

    在配置文件 setting json 中加入如下代码即可 34 code runner executorMap 34 34 python 34 34 set PYTHONIOENCODING 61 utf8 amp amp python u
  • 【PAT】B1019 数字黑洞

    给定任一个各位数字不完全相同的 4 位正整数 xff0c 如果我们先把 4 个数字按非递增排序 xff0c 再按非递减排序 xff0c 然后用第 1 个数字减第 2 个数字 xff0c 将得到一个新的数字 一直重复这样做 xff0c 我们很
  • 【PAT】B1030 完美数列

    给定一个正整数数列 xff0c 和正整数 p xff0c 设这个数列中的最大值是 M xff0c 最小值是 m xff0c 如果 M mp xff0c 则称这个数列是完美数列 现在给定参数 p 和一些正整数 xff0c 请你从中选择尽可能多
  • 【PAT】B1025 反转链表

    给定一个常数 K 以及一个单链表 L xff0c 请编写程序将 L 中每 K 个结点反转 例如 xff1a 给定 L 为 1 2 3 4 5 6 xff0c K 为 3 xff0c 则输出应该为 3 2 1 6 5 4 xff1b 如果 K
  • jupyter notebook中安装完nb_conda后,change kernel中仍然没有所需环境

    问题前解 xff1a jupyter notebook创建新的环境时遇到困难解决笔记 没有所需环境 xff0c 但按上述解决方案解决过 问题解决方案 xff1a 需要增加kernel xff1a python m ipykernel ins
  • 使用Code:Blocks调试程序

    首先 xff0c 工程路径必须是英文 xff0c 不然根本打不开Debug模式 鼠标停留在debug栏按钮上会显示名称 将光标移至代码开始行 xff08 自定 xff0c 如程序有scanf xff0c 建议移至scanf下一行 xff09
  • 对string类型sort

    algorithm算法库里的sort函数超级好用 xff0c 那么怎么将string类型当成字符数组一样进行排序呢 只要将需要排序的string的首尾地址放入就行啦 也可以用自己写的cmp函数当成排序规则 传参就可以 include lt
  • BFS算法求迷宫的最短路径

    BFS Breadth First Search 算法的具体实现就是 xff1a 通过不断取得某个状态能够达到的所有状态并将其加入队列尾 xff0c 并且由于队列本身的特性先加入队列的状态总是先得到处理 xff0c 这样就可以总是先将需要转