[bfs最短路] aw1076. 迷宫问题(bfs最短路+模板题)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bfs最短路] aw1076. 迷宫问题(bfs最短路+模板题)相关的知识,希望对你有一定的参考价值。
1. 题目来源
链接:1076. 迷宫问题
相同:[bfs] aw844. 走迷宫(模板题+bfs最短路模型+经典)
2. 题目解析
经典的 bfs
找二维迷宫最短路径问题,还要输出最短路径。需要记录每个格子的上一步是从哪来的。
bfs
第一次搜到的一定是该格子的最短路径。最后输出路径的时候,从后向前推一遍即可。
小技巧:
- 我们只能记录最短路径格子的上一个格子是多少,且必须从后往前推。
- 如果从
(0, 0)
点开始走到终点(n-1, n-1)
的话,再从(n-1,n-1)
推到(0, 0)
的话,其实是与答案相反的。 - 所以可以从
(n-1, n-1)
开始走,走到(0, 0)
,这样从(0, 0)
推到(n-1, n-1)
的话就是正向最短路径了。
时间复杂度: O ( n m ) O(nm) O(nm)
空间复杂度: O ( n m ) O(nm) O(nm)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 1005;
int n;
int g[N][N];
PII pre[N][N];
PII q[N * N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void bfs(int sx, int sy) {
int hh = 0, tt = 0;
q[0] = {sx, sy};
memset(pre, -1, sizeof pre); // 初始化为无效状态
pre[sx][sy] = {0, 0}; // 起点的上一步无所谓
while (hh <= tt) {
auto t = q[hh ++ ];
int x = t.first, y = t.second;
for (int i = 0; i < 4; i ++ ) {
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= n) continue;
if (g[a][b]) continue;
if (pre[a][b].first != -1) continue; // 若当前位置存了上步来源,则说明当前位置被搜过
q[ ++ tt ] = {a, b};
pre[a][b] = {x, y};
}
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
scanf("%d", &g[i][j]);
bfs(n - 1, n - 1); // 从终点往起点走,每次存一下上步来源,则从起点推到终点即为最短路径
int x = 0, y = 0;
while (true) {
printf("%d %d\\n", x, y); // 先打印
if (x == n - 1 && y == n - 1) break;
auto t = pre[x][y];
x = t.first, y = t.second;
}
return 0;
}
以上是关于[bfs最短路] aw1076. 迷宫问题(bfs最短路+模板题)的主要内容,如果未能解决你的问题,请参考以下文章