zoukankan      html  css  js  c++  java
  • 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             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             }
    getchar();
    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 */
  • 相关阅读:
    bzoj 3930: [CQOI2015]选数
    bzoj 2301: [HAOI2011]Problem b
    HDU 1695 GCD
    2017ACM/ICPC广西邀请赛-重现赛 1007.Duizi and Shunzi
    2017ACM/ICPC广西邀请赛-重现赛 1010.Query on A Tree
    2017ACM/ICPC广西邀请赛-重现赛 1004.Covering
    P3501 [POI2010]ANT-Antisymmetry
    P1171 售货员的难题
    P3385 【模板】负环
    P1659 [国家集训队]拉拉队排练
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/9303054.html
Copyright © 2011-2022 走看看