BFS求最短路

假设有一个n行m列的迷宫,每个单位格要么是空地(用1来表示)要么是障碍物(用0来表示).如何找到从起点到终点的最短路径?

分析:要找到终点到起点的最短路径,可以使用二叉树的BFS,因为二叉树的BFS的访问顺序就是结点到根节点的距离,从小到大访问的,因此可以从迷宫图的起点开始进行BFS的宽度优先遍历。

遍历过程中需要实现:

(1)记录每个结点到起点的距离;

(2)记录每个结点的父结点,构造出BFS二叉树,根据该树,给出任意一个空地的座标,都可以根据父节点回溯到起点(0,0);

(3)每一个结点都要访问其上下左右四个方向,并判断每个方向的节点位置是否合格,合格的加入队列;

遍历成功后,根据给出终点位置,使用递归来输出起点到该终点的路径;

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 const int maxn = 5;
 6 struct Node{
 7     int x;
 8     int y;
 9     Node(int x = 0,int y = 0):x(x),y(y){}
10 }; 
11 int graph[maxn][maxn]; //迷宫数组 
12 int dis[maxn][maxn];   //记录每个结点到起点的距离 
13 struct Node path[maxn][maxn]; //记录每个结点的父节点 
14 const int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; //每个结点的四个方向 
15 bool judge(int dr,int dc){
16     if(dr >= 0 && dr < maxn && dc >= 0 && dc < maxn 
17     && dis[dr][dc] == -1 && graph[dr][dc]){
18         return true;
19     }
20     return false;
21 } 
22 
23 void bfs(){    //宽度遍历迷宫,构造BFS树(最短路树)
24     memset(dis,-1,sizeof(dis)); 
25     queue<Node> q;
26     q.push(Node(0,0));  //规定迷宫的起点是(0,0) 
27     dis[0][0] = 0;
28     while(!q.empty()){
29         Node n = q.front();q.pop();
30         for(int i = 0;i < 4;i++){
31             int dr = n.x + dir[i][0];
32             int dc = n.y + dir[i][1];
33             if(judge(dr,dc)){
34                 dis[dr][dc] = dis[n.x][n.y] + 1;
35                 q.push(Node(dr,dc));
36                 path[dr][dc] = n; 
37             }
38         }
39     }    
40 }
41 void print_path(int r,int c){
42     Node n = path[r][c];
43     if(n.x == 0 && n.y == 0){    //回溯到起点 
44         cout << "(0,0)" << " ";
45         return;
46     }
47     print_path(n.x,n.y);
48     cout << "(" << r << "," << c << ")" << " "; 
49 } 
50 int main(){
51     for(int i = 0;i < maxn;i++){    //输入迷宫 
52         for(int j = 0;j < maxn;j++){
53             cin >> graph[i][j];
54         }
55     }
56     bfs(); 
57     print_path(4,4);
58     return 0;
59 } 

 

posted @ 2020-03-28 15:48  争不过朝夕  阅读(362)  评论(0编辑  收藏  举报