BFS例题详解

来源:互联网 发布:xampp怎么切换php版本 编辑:程序博客网 时间:2024/05/05 16:58

这道题目均来自白书第34页-36页;

个人觉得这个例题很好地表现了广度优先搜索是如何与队列先进先出(FIFO)的思想联系起来的,通过不断取得某个状态后能够达到的所有状态并将其加入队列, 并且由于队列本身的特性先加入队列的状态总是先得到处理,这样就达到了一个目的:总是先将需要转移次数更少的状态进行分析处理,换句话说就是总是取得了这个状态的树中更接近根部的节点,又或者是总是让搜索树的广度得到尽可能增加。

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

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

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

3.循环2直到将终点添加到队列中,这说明我们已经找到了路径;

注意到在这个过程中,每次处理的位置所对应的距离是严格递增的,因此一旦找到终点,当时的距离就是最短距离;

同样基于这个原因,搜索可移动到的位置所使用的判断条件中不仅仅是不碰墙壁、不超过边界,还有一个就是没有到达过,因为如果已经到达了这个位置,这说明已经有更短的路径到达这个位置,这次到达这个位置的路径是更差的,不可能得到更好的最终解。

源代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. #include <queue>  
  3. using namespace std;  
  4. const int MAX_N = 100;  
  5. const int MAX_M = 100;  
  6. const int INF = 0x3f3f3f3f;  
  7. typedef pair<intint> P;  
  8. char maze[MAX_N][MAX_M + 1];  
  9. int N, M;  
  10. int sx, sy; //起点的位置  
  11. int gx, gy; //终点的位置  
  12.   
  13. int d[MAX_N][MAX_M];//储存起点到某一点的距离  
  14. int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; //表明每次x和y方向的位移  
  15.   
  16. void bfs()  
  17. {  
  18.     queue<P> que;  
  19.     for (int i = 0; i < N; i++)  
  20.         for (int j = 0; j < M; j++)  
  21.             d[i][j] = INF;  //初始化所有点的距离为INF  
  22.     que.push(P(sx, sy));  
  23.     d[sx][sy] = 0;  //从起点出发将距离设为0,并放入队列首端  
  24.   
  25.     while (que.size()) //题目保证有路到终点,所以不用担心死循环  
  26.     {  
  27.         P p = que.front(); que.pop();//弹出队首元素  
  28.         int i;  
  29.         for (i = 0; i < 4; i++)  
  30.         {  
  31.             int nx = p.first + dx[i];  
  32.             int ny = p.second + dy[i];//移动后的坐标  
  33.             //判断可移动且没到过  
  34.             if (0 <= nx&&nx < N  
  35.                 && 0 <= ny&&ny < M  
  36.                 &&maze[nx][ny] != '#'  
  37.                 &&d[nx][ny] == INF)//之前到过的话不用考虑,因为距离在队列中递增,肯定不会获得更好的解  
  38.             {  
  39.                 que.push(P(nx, ny));    //可以移动则设定距离为之前加一,放入队列  
  40.                 d[nx][ny] = d[p.first][p.second] + 1;  
  41.                 if(nx==gx && ny==gy) break;  
  42.   
  43.                         }  
  44.         }  
  45.         if(i!=4) break;  
  46.     }  
  47.   
  48. }  
  49.   
  50. int main()  
  51. {  
  52.     cin>>N>>M;  
  53.     for (int i = 0; i < N; i++)  
  54.         cin>>maze[i];  
  55.     for (int i = 0; i < N; i++)  
  56.         for (int j = 0; j < M; j++)  
  57.         {  
  58.             if (maze[i][j] == 'S')  
  59.             {  
  60.                 sx = i; sy = j;  
  61.             }  
  62.             if (maze[i][j] == 'G')  
  63.             {  
  64.                 gx = i; gy = j;  
  65.             }  
  66.         }  
  67.     bfs();  
  68.     cout<<d[gx][gy]<<endl;  
  69.   
  70.     return 0;  
  71. }  
声明:本文来自Jason Ranger的CSDN博客,链接:http://m.blog.csdn.net/article/details?id=50768661
原创粉丝点击