AcWing 1076 迷宫问题
需要注意:pre[i][j]记录的是逆推的情况下,[i, j]是从哪个点过来的,也就是正推的情况下,最短路径上,[i, j]的下一个点,所以需要逆推一遍bfs,然后正序输出
#include<bits/stdc++.h>
using namespace std;
const int N = 1010, M = N * N;
#define x first
#define y second
typedef pair<int, int>PII;
int n;
int g[N][N];
PII q[M];
PII pre[N][N];
bool st[N][N];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
void bfs(int sx, int sy){
st[sx][sy] = true;
q[0] = {sx, sy};
memset(pre, -1, sizeof pre);
int hh = 0, tt = 0;
while(hh <= tt){
auto t = q[hh ++ ];
for(int i = 0; i < 4; i ++ ){
int xx = t.x + dx[i], yy = t.y + dy[i];
if(xx < 0 || xx >= n || yy < 0 || yy >= n) continue;
if(g[xx][yy]) continue;
if(pre[xx][yy].x != -1) continue; //表示xx、yy这个点不是第一次被遍历到,那就直接跳过
q[ ++ tt] = {xx, yy};
st[xx][yy] = true;
pre[xx][yy] = t; //表示[xx,yy]是从t过来的(逆着)
}
}
}
int main()
{
cin>>n;
for(int i = 0; i < n; i ++ ){
for(int j = 0; j < n; j ++ ){
cin>>g[i][j];
}
}
bfs(n - 1, n - 1);
PII end(0, 0);
while(true){
cout<<end.x<<' '<<end.y<<endl;
if(end.x == n - 1 && end.y == n - 1) break;
end = pre[end.x][end.y]; //pre[i][j]记录的是逆序时那个点到[i,j]的,自然就是正着的时候[i,j]的下一个点
}
return 0;
}