用bfs求迷宫最短路径(当所有边权重都一样时,才可用宽搜bfs)
一、仅求最短路版
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 110;
typedef pair<int,int> PII;
int n,m;
int g[N][N],d[N][N];//g存地图,d存每个点到起点的距离
PII q[N*N];//定义一队列(存储的是路径下标)
int bfs()
{
int hh = 0,tt = 0;//初始化队头队尾
q[0] = {0,0};
memset(d,-1,sizeof d);//先把所有距离初始化成-1,表示未走过
d[0][0] = 0;//标记起点距离为0
int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};//定义四个方向的偏移量,依次为上右下左(同蛇形矩阵)
while(hh<=tt){//当队列不空
auto t = q[hh++];//取出队头
for(int i=0; i<4; i++)//往四个方向扩展队头
{
int x = t.first+dx[i], y = t.second+dy[i];//更新路径下标
//判断路径下标是否越界,如果仍在边界内且该点是空地以及未被走过
if(x>=0 && x<n && y>=0 && y<m && g[x][y]==0 && d[x][y]==-1)
{ //在第一次搜到的时候才更新该点到起点的距离
d[x][y] = d[t.first][t.second]+1;
q[++tt] = {x,y};//将该点加入路径队列
}
}
}
return d[n-1][m-1];//返回终点到起点距离
}
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
cin>>g[i][j];
cout<<bfs();
return 0;
}
二、可倒序输出路径版
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 110;
typedef pair<int,int> PII;
int n,m;
int g[N][N],d[N][N];//g存地图,d存每个点到起点的距离
PII q[N*N],pre[N][N];//定义一队列q(存储的是路径下标),pre存该点在路径中的前一个点
void bfs()
{
int hh = 0,tt = 0;//初始化队头队尾
q[0] = {0,0};
memset(d,-1,sizeof d);//先把所有距离初始化成-1,表示未走过
d[0][0] = 0;//标记起点距离为0
int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};//定义四个方向的偏移量,依次为上右下左(同蛇形矩阵)
while(hh<=tt){//当队列不空
auto t = q[hh++];//取出队头
for(int i=0; i<4; i++)//往四个方向扩展队头
{
int x = t.first+dx[i], y = t.second+dy[i];//更新路径下标
//判断路径下标是否越界,如果仍在边界内且该点是空地以及未被走过
if(x>=0 && x<n && y>=0 && y<m && g[x][y]==0 && d[x][y]==-1)
{ //在第一次搜到的时候才更新该点到起点的距离
d[x][y] = d[t.first][t.second]+1;
pre[x][y] = t; //记录该点的前一个点
q[++tt] = {x,y};//将该点加入路径队列
}
}
}
int x = n-1, y = m-1;//从终点开始倒序输出路径
while(x || y){//当未到达起点时
cout<<x<<' '<<y<<endl;
auto t = pre[x][y];
x = t.first; y = t.second;
}
}
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
cin>>g[i][j];
bfs();
return 0;
}