BFS求解迷宫的最短路径问题

题目:给定一个大小为N*M的迷宫,迷宫由通道(‘.‘)和墙壁(‘#‘)组成,其中通道S表示起点,通道G表示终点,每一步移动可以达到上下左右中不是墙壁的位置。试求出起点到终点的最小步数。(本题假定迷宫是有解的)(N,M<=100)

输入:

10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

输出:

22

本题目与解题思路均来源于挑战程序设计竞赛(第二版),是个经典的将BFS与队列(先进先出)特性紧密结合问题。广度优先搜索(BFS)按照距开始状态由近及远的顺序进行搜索,因此很容易地用来求最短路径、最少操作之类的问题。我们可以用所在的位置表状态,转移的方式为四方向移动,只要将已经访问过的状态用标记管理起来,就可以很好地做到由近及远的搜索。由于要求最短距离,不妨用dis[n][m]数组把最短距离保存起来,初始用非常大的常熟inf来初始化它,这样尚未到达的的位置就是inf,也就同时起了标记的作用。虽然到达终点时就会停止搜索,可如果继续下去直到队列为空的话,就可以计算出到各个位置的最短距离。此外,若搜索到最后,dis依然为inf,便可得知这个位置是无法从起点到达。

附上代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 using namespace std;
 5 typedef pair<int,int> pa;
 6 const int inf=0x3f3f3f3f;
 7 char map[105][105];  //表示迷宫的字符串数组
 8 int n,m;
 9 int sx,sy;   //起点坐标
10 int gx,gy;   //终点坐标
11 int dis[105][105];  //保存起点到各点最短距离
12 queue<pa> q;
13 const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};  //表示x和y可以移动的四个方向
14 int bfs()
15 {
16     for(int i=0;i<n;i++){
17         for(int j=0;j<m;j++){
18             dis[i][j]=inf;   //将起点到各点的距离初始化为无穷大,表示为到达
19         }
20     }
21     q.push(pa(sx,sy));
22     dis[sx][sy]=0;  //从起点出发将距离设为0 ,并放入队列
23     //不断循环直到队列的长度为0
24     while(q.size())
25     {
26         //取出队首元素
27         pa p=q.front();
28         q.pop();
29         //如果取出的状态是终点,则结束搜索
30         if(p.first==gx&&p.second==gy) break;
31         //四个方向的循环
32         for(int i=0;i<4;i++)
33         {
34             //移动之后的坐标记为(dx,dy)
35             int dx=p.first+dir[i][0];
36             int dy=p.second+dir[i][1];
37             //判断是否已经访问过,如果dis[dx][dy]不为inf即为已经访问过
38             if(dx>=0&&dx<n&&dy>=0&&dy<m&&map[dx][dy]!=‘#‘&&dis[dx][dy]==inf)
39             {
40                 //可以移动的话,则加入到队列,并且该位置的距离确定为到p的距离加1
41                 q.push(pa(dx,dy));
42                 dis[dx][dy]=dis[p.first][p.second]+1;
43             }
44         }
45      }
46      return dis[gx][gy];
47 }
48 int main()
49 {
50     cin>>n>>m;
51     getchar();
52     for(int i=0;i<n;i++){
53         for(int j=0;j<m;j++){
54             getchar();
55             scanf("%c",&map[i][j]);
56             if (map[i][j] == ‘S‘)
57             {
58                 sx=i; sy=j;
59             }
60             if (map[i][j] == ‘G‘)
61             {
62                 gx=i; gy=j;
63             }
64             }
65         }
66     int ans=bfs();
67     cout<<ans<<endl;
68     return 0;
69 }
70 /*
71 10 10
72 #S######.#
73 ......#..#
74 .#.##.##.#
75 .#........
76 ##.##.####
77 ....#....#
78 .#######.#
79 ....#.....
80 .####.###.
81 ....#...G#
82 22
83 */

原文地址:https://www.cnblogs.com/zjl192628928/p/9303054.html

时间: 2024-10-12 14:26:23

BFS求解迷宫的最短路径问题的相关文章

BFS求解迷宫最短路径

本文使用BFS广度优先搜索算法实现求解迷宫的最短路径(C++),使用到了队列先进先出的性质,依次搜索路径直到找到目标出口(如果迷宫能走通)求解到的路径即为该迷宫的最短路径,找到返回true,找不到返回false,本文使用vexmap一个map容器记录队列的搜索路径(记录队列路径的实现有点草率,可以再优化).</p><p> </p><pre class="cpp" name="code">#include<iost

迷宫的最短路径(BFS的简单应用)

[题目简述]:给定一个大小为n*m的迷宫.迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四格的通道移动.请求出起点到终点所需的最小步数.(注:本题假定从起点一定可以移动到终点) 如图: #S######.# ......#..# .#.##.##.# .#........ ##.##.#### ....#....# .#######.# ....#..... .####.###. ....#...G# [分析]:广度优先搜索是由近及远的搜索,所以在这个问题中采用BFS很合适,只要注意访问过的位

编程算法 - 迷宫的最短路径 代码(C++)

迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步可以向邻接的上下左右四格的通道移动. 请求出从起点到终点所需的最小步数. 请注意, 本题假定从起点一定可以移动到终点. 使用宽度优先搜索算法(DFS), 依次遍历迷宫的四个方向, 当有可以走且未走过的方向时, 移动并且步数加一. 时间复杂度取决于迷宫的状态数, O(4*M*N)=O(M*N). 代码: /* * m

数据结构之迷宫问题求解(二)迷宫的最短路径

上篇文章我们讨论了,迷宫问题的普通求解问题,这篇文章我们继续深入,求迷宫的最短路径. 要想求迷宫的最短路径,一个很简单的方法就是再设置一个Min栈,用来放最短路径,每找到一个出口,就将path栈与Min栈进行比较,如果path栈更小,则赋值给Min. 而在上篇文章中,我们将走过的路径做了标记,每走一个坐标,就把那个坐标置为3,直至找到出口. 因此如果用这种标记方式,显然是会出现问题的. 所以我们需要换种标记方式! 最终....我决定,使出口的值为2,每走一步使当前位置标记变为是上一位置标记再加1

蚁群算法求解迷宫最优路径问题

本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新 和为每一只蚂蚁选择下一个方格. 一共会进行RcMax = 2000轮模拟(理论上模拟的次数越多结果 会越接近真实值),而在每一轮中会排除 M = 10只蚂蚁进行探路.同时在算法的回溯思想上采用的 是栈的数据结构来实现的.当栈最终为空时则表示无解.但同时这段程序的一缺点就是:由于我没在 算法中对每一轮的每只探路蚂蚁采用多线程的模式,所以整体的运行效率还不是很高.如读者有好的 思想或建议,请留言. #include<io

hdu1180诡异的楼梯……bfs走迷宫……wa了16次,我太渣了

#include<iostream> #include<queue> #include<cstring> using namespace std; int row,line,xx[4]={-1,1,0,0},yy[4]={0,0,-1,1}; char map[100][100]; bool vis[100][100]; struct node { int x,y,step; }st; void init() { int i,j; bool flag=1; for(i=

利用数据结构栈求解迷宫问题

本段程序主要利用数据结构栈的先进后出特点,实现回溯求解迷宫路径问题. #include<iostream> #include<stack> using namespace std; //坐标类 struct Point { int x; int y; }; //地图类 template<int A> struct Map { int (*p)[A]; int row;//行数 int col;//列数 }; //start起始点, end终止点 template<

利用栈求解迷宫问题

利用栈求解迷宫问题 源代码: #include<stdio.h> #include<stdlib.h> #define M 8 #define N 8 #define MaxSize M*N typedef struct { int i;//当前方块的行号 int j;//当前方块的列号 int di; //di是下一个可走的相邻方块的方位号 }Box; typedef struct { Box data[MaxSize]; int top;      //栈顶指针 }StType

Bellman-Ford算法——求解单源点最短路径问题

Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好好思考),而Dijkstra算法只能处理边权非负的问题,因此 Bellman-Ford算法的适用面要广泛一些.但是,原始的Bellman-Ford算法时间复杂度为O(VE),比Dijkstra算法的时间复杂度高,所以常常被众多的大学算法教科书所忽略,就连经典的<算法导论>也只介绍了基本的Bellm