广度优先搜索(BFS)——迷宫的最短路径
宽度优先搜索按照距开始状态由近到远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案。
宽度优先搜索介绍(一篇不错的文章)。
题目描述:
给定一个大小为N*M的迷宫。迷宫有通道和墙壁组成,每一步可以向邻接的上下左右的通道移动。请求出从起点到终点所需要的最小步数。
例如,N为10, M为10,输入的迷宫如下表示,其中S表示起点,G表示终点,"."表示通道,“#”表示墙壁
样例输入:
10 10
S######.
......#..#
.#.##.##.#
.#........
.##.
....#....#
.#######.#
....#.....
.####.###.
....#...G#
样例输出:
22
思路:
用到队列(queue),并且在本例中定义了新的数据类型P,while (que.size())真段代码是说,如果队列的长度为0.则终止循环,就像是排着个长队一样,
从队首开始,判断一个,取出,然后放入下一个,知道找到最终的。中间都去除了,距离为0
在这个问题中,找到从起点到终点的最短路径其实就是一个建立队列的过程:
1.从起点开始,先将其加入队列,设置距离为0;
2.从队列首端取出位置,将从这个位置能够到达的位置加入队列,并且让这些位置的距离为上一个位置的距离加上1;
3.循环2直到将终点添加到队列中,这说明我们已经找到了路径;
注意到在这个过程中,每次处理的位置所对应的距离是严格递增的,因此一旦找到终点,当时的距离就是最短距离;
同样基于这个原因,搜索可移动到的位置所使用的判断条件中不仅仅是不碰墙壁、不超过边界,还有一个就是没有到达过,因为如果已经到达了这个位置,这说明已经有更短的路径到达这个位置,这次到达这个位置的路径是更差的,不可能得到更好的最终解。
AC代码:
# include <iostream>
# include <queue>
using namespace std;
const int MAX_N = 100;
const int MAX_M = 100;
const int INF = 1000000;//初始时用充分大的常数INF来初始化,这样尚未达到的位置就是INF,同时标记
typedef pair<int, int> P;
char maze[MAX_N][MAX_M+1];
int N, M;//行/列
int sx, sy;//起点的位置
int gx, gy;//终点的位置
int d[MAX_N][MAX_N];//储存起到某一点的距离
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0. - 1 };//表明每次x和y方向的位移
//分别是(1,0)(0,1)(-1,0)(0,-1)
void bfs()
{
queue<P> que;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
d[i][j] = INF;//初始化所有点的距离为INF
}
que.push(P(sx, sy));//因为P是新定义的,可以直接把二维数组的下标放进去,和C语言的结构体类似
d[sx][sy] = 0;//从起点出发将距离设置为 0,并放入队列首段
while (que.size())//题目保证路有终点,直到队列的长度为0 为止
{
P p = que.front(); que.pop();
int i;
for (i = 0; i < 4; i++)
{
int nx = p.first + dx[i];
int ny = p.second + dy[i];//因为p是新声明的数据类型P的一个子数据,P中有两个,一个是横坐标,一个是纵坐标
//移动后的坐标
//判断可移动且没到过
if (0 <= nx&&nx < N
&& 0 <= ny&&ny < M
&&maze[nx][ny] != '#'
&&d[nx][ny] == INF)
//之前到过的话不用考虑,因为距离在队列中递增,肯定不会获得更好的解
{
que.push(P(nx, ny)); //可以移动则设定距离为之前加一,放入队列 (队列的运算)
d[nx][ny] = d[p.first][p.second] + 1;
if (nx == gx && ny == gy) break;
}
}
if (i != 4) break;
}
}
int main()
{
cin >> N >> M;
for (int i = 0; i < N; i++)
cin >> maze[i];
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
{
if (maze[i][j] == 'S')
{
sx = i; sy = j;
}
if (maze[i][j] == 'G')
{
gx = i; gy = j;
}
}
bfs();
cout << d[gx][gy] << endl;
return 0;
}
广度优先搜索(BFS)——迷宫的最短路径的更多相关文章
- 广度优先搜索 BFS 学习笔记
广度优先搜索 BFS 学习笔记 引入 广搜是图论中的基础算法之一,属于一种盲目搜寻方法. 广搜需要使用队列来实现,分以下几步: 将起点插入队尾: 取队首 \(u\),如果 $u\to v $ 有一条路 ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析
转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...
- 【数据结构与算法Python版学习笔记】图——词梯问题 广度优先搜索 BFS
词梯Word Ladder问题 要求是相邻两个单词之间差异只能是1个字母,如FOOL变SAGE: FOOL >> POOL >> POLL >> POLE > ...
- 广度优先搜索(BFS)
定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...
- 广度优先搜索--POJ迷宫问题
Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, ...
- 广度优先搜索 BFS算法
广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS
前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...
随机推荐
- 坏块管理(Bad Block Management,BBM)
看了很多坏块管理的文章,加上自己的理解,把整个坏块管理做了个总结. 坏块分类 1.出厂坏块 又叫初始坏块,厂商会给点最小有效块值(NVB,mininum number of valid blocks) ...
- Android学习笔记-TextView(文本框)(二)
2.4 使用autoLink属性识别链接类型 当文字中出现了URL,E-Mail,电话号码,地图的时候,我们可以通过设置autoLink属性:当我们点击 文字中对应部分的文字,即可跳转至某默认APP, ...
- nopCommerce 3.9 大波浪系列 之 可退款的支付宝插件(下)
一.回顾 支付宝插件源码下载地址:点击下载 上篇介绍了使用支付宝插件进行支付,全额退款,部分退款还有插件的多店铺配置,本文介绍下如何实现的. 二.前期准备 插件主要有3个功能: 多店铺插件配置 支付功 ...
- 15. leetcode 349. Intersection of Two Arrays
Given two arrays, write a function to compute their intersection. Example: Given nums1 = [1, 2, 2, 1 ...
- Java集合框架Collections【List/Set】
1.基本介绍: 集合就是存放对象的,他比数组好的一点就是他一开始不清楚自己长度 容器一般是分为很多种的,很多的容器在一起然后进过断的抽象和抽取就成了一个体系,我们称之为集合框架 我们看体系首先是看顶层 ...
- vc操作电脑之常用命令
1.重启计算机: ExitWindowsEx(EWX_REBOOT,0); 2.关机: ExitWindowsEx(EWX_SHUTDOWN,0); 3.注销: ExitWindowsEx(EWX_L ...
- python--DenyHttp项目(1)--socket编程:客户端与服务器端
查找了许多资料,实现了客户端与服务器端的连接,通过虚拟机进行测试 服务器端IP:192.168.37.129 端口1122 客户端IP: 192.168.37.1 端口1122 Server: #co ...
- Java 线程宝典
此文 为垃圾文 本人复习用的 emmm 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程 并行与并发: 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时. 并发:通过cpu ...
- 一步一步学多线程-Timer
在执行定时任务的时候可以用Timer来实现,现在小编对学到的进行一次总结,先来看一个demo 1 public class TimerTest { 2 3 public static void mai ...
- C++ Socket学习记录 -3
WinSocket套接字之间的数据传输 在客户端和服务端建立链接后,接着就是在套接字之间传输数据. 很简单的使用 recv 接收数据,用send发送数据,单但是出现一个问题,不管接收还是发送,数据都是 ...