思路:这道题不仅要求判断迷宫是否有出路,还要求出出迷宫的最短时间(最短步数),即迷宫最短路问题,使用dfs的话由于不能走重复路径,会导致一条路走出去之后可能不是最短路径,所以使用bfs是最优解。想法就是通过一个队列来记录每一次走到该点的前点坐标,进行一层一层的遍历,再同时记录到达的每一点距离起点的最短距离,就能保证最后路径一定是最短路
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int mp[N][N];
bitset<N>vis[N];//用来记录某一点是否已经经过
int n, m;
int d[N][N];//记录一点距离起始点的最短距离
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
bool inmp(int x,int y) {//判断这一点是否在地图内,即是否移动出界
return x >= 1 && x <= n && y >= 1 && y <= m;
}
void bfs(int sx,int sy) {//求权值最小的最短路
queue<pair<int, int>>q;//队列q的每层存放一个x,y的值
memset(d, 0x3f, sizeof d);//将d数组内元素初始化为无穷
d[sx][sy] = 0;//初始位置距离起点距离为0
q.push({ sx,sy });//将初始位置添加到队列
while (q.size()) {
int x = q.front().first, y = q.front().second;//
q.pop();
if (vis[x][y])continue;//该点如果走过,则跳过这一步循环
vis[x][y] = true;
for (int i = 0; i < 4; ++i) {//从x,y尝试遍历下上右左方向
int nx = x + dx[i], ny = y + dy[i];
if (inmp(nx,ny) && !mp[nx][ny] && d[nx][ny] > d[x][y] + 1) {//这一点在地图内且下一步无障碍,并且通过这一步可以使到达该点步数更短
d[nx][ny] = d[x][y] + 1;
q.push({ nx,ny });//下一步的x,y坐标入队
}
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i=1;i<=n;++i)
for (int j = 1; j <= m; ++j) {
cin >> mp[i][j];
}
bfs(1, 1);
if (!vis[n][m])cout << -1 << '\n';//最后的出口未达到说明迷宫无法通过
else cout << d[n][m] << '\n';
return 0;
}