宽度优先搜索按照距开始状态由近到远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案
宽度优先搜索介绍(一篇不错的文章)。

题目描述:

给定一个大小为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)——迷宫的最短路径的更多相关文章

  1. 广度优先搜索 BFS 学习笔记

    广度优先搜索 BFS 学习笔记 引入 广搜是图论中的基础算法之一,属于一种盲目搜寻方法. 广搜需要使用队列来实现,分以下几步: 将起点插入队尾: 取队首 \(u\),如果 $u\to v $ 有一条路 ...

  2. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  3. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  4. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

  5. 【数据结构与算法Python版学习笔记】图——词梯问题 广度优先搜索 BFS

    词梯Word Ladder问题 要求是相邻两个单词之间差异只能是1个字母,如FOOL变SAGE: FOOL >> POOL >> POLL >> POLE > ...

  6. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

  7. 广度优先搜索--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, ...

  8. 广度优先搜索 BFS算法

    广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...

  9. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  10. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

随机推荐

  1. (转)在Linux里设置用户环境变量的方法

    背景:在linux下,root用户安装完jdk后,非root用户不能使用java环境变量. 问题排查: 通过在root和非root用户下分别执行echo $PATH 可以观察环境变量的异同.然后将需要 ...

  2. 【SignalR学习系列】1. SignalR理论介绍

    什么是SignalR? ASP.NET SignalR 是一个让 ASP.NET开发者可以简单地给自己的程序添加即时通讯功能的开发库.即时通讯功能可以直接从服务器端给在线的客户端发送数据,而不用等待客 ...

  3. 【Lab】Python改bat文件

    [Lab]Python改bat文件 给出一个特定的树形结构,每一层的数字依次递增后,按照从上到下,同时从左到右这样的顺序生成.这么说还是不太明白,比如下面这个简单的树形结构. 按照顺序应该写成这样[3 ...

  4. [补档][Poi2010]Monotonicity 2

    [Poi2010]Monotonicity 2 题目 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. 选出一个长度为L的子序列(不要求连续),要求这个子序列 ...

  5. Python应用场景

    Web应用开发 Python经常被用于Web开发.比如,通过mod_wsgi模块,Apache可以运行用Python编写的Web程序.Python定义了WSGI标准应用接口来协调Http服务器与基于P ...

  6. HashMap 源码解读

    HashMap在JDK1.7和1.8中有了很大的改变,空闲时间对HashMap做了一点点的研究. HashMap是一种数组和链表结合的数据结构,我们每次new一个HashMap时,都会构造出一个长度为 ...

  7. akoj-1267-独木舟上的荡漾

    独木舟上的荡漾 Time Limit:1000MS  Memory Limit:65536K Total Submit:76 Accepted:44 Description 进行一次独木舟的旅行活动, ...

  8. oracle中decode的一些巧妙用法

    1.符号函数sign在decode中的用法--比较大小 select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值sign()函数根据某个值是0 ...

  9. Linux - 简明Shell编程08 - 函数(Function)

    脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash function Check( ...

  10. Hibernate(三)

    1.1Hibernate的检索方式 1.1.1Hibernate的检索方式概述 Hibernate提供了以下几种检索对象的方式: 导航对象图检索方式:根据已经家就在的对象导航到其他对象. Custom ...