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 }