BFS介绍:
宽度搜索优先按照距开始状态由近及远的顺序进行搜索,因此可以很容易用来求最短路径、最少操作之类问题的答案。它是按照开始状态->只需1次转移就能到达的所有状态->只需2次就能到达的所有状态->...这样的顺序进行搜索。对于同一个状态,bfs只经过一次,时间复杂度为O(状态数*转移方式)。BFS搜索利用了队列,搜索时首先将初始状态添加对队列中,此后不断从队列中取出状态,并把从该状态可以转到的所有状态添加到队列中,如此往复,直到队列为空或者找到解。
迷宫问题:
给定一个大小为N*M的迷宫,迷宫由通道和墙壁组成('#','.','S','G'分别表示墙、通道、起点和终点),每一步可以向邻接的上下左右四个方向移动。请给出从起点到终点所需的最小步数。假定起点一定可以到达终点。
源码如下:
#include <iostream>
#include <queue>
using namespace std;
//定义常量 无法到达
const int INF=1000000000;
//定义迷宫规模
const int MAXN=100;
const int MAXM=100;
//自定义数据类型 存储所处位置
typedef pair<int,int> Pair;
char migong[MAXN][MAXM];
int N,M;
//定义迷宫入口和出口位置
int sx,sy,gx,gy;
//定义标记数组,记录每个位置所走过的距离
int flag[MAXN][MAXM];
//定义前进方向,分别为右、下、左、上,往不同方向前进时x y坐标同步变化
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int bfs(){
queue<Pair> q;
//初始化距离数组,全部为不可到达
for(int i=0;i<N;i++)
for(int j=0;j<M;j++) flag[i][j]=INF;
//将起点入队
q.push(Pair(sx,sy));
//起始点距离为0
flag[sx][sy]=0;
while(q.size()){
//取得当前所处位置坐标并将该点从队列中移除
Pair p=q.front();q.pop();
//如果到达终点 ,结束循环
if(p.first==gx && p.second==gy)
break;
//尝试向四个方向前进
for(int i=0;i<4;i++){
int nx=p.first+dx[i];
int ny=p.second+dy[i];
//防止坐标溢出,同时判断是否碰到墙壁或者走回原路
if(nx>=0 && nx<N && ny>=0 && ny<M && migong[nx][ny]!='#' && flag[nx][ny]==INF){
q.push(Pair(nx,ny));
flag[nx][ny]=flag[p.first][p.second]+1;
}
}
}
return flag[gx][gy];
}
int main ()
{
cin>>N>>M;
for(int i=0;i<N;i++)
for(int j=0;j<M;j++){
cin>>migong[i][j];
//记录入口位置
if(migong[i][j]=='S'){
sx=i;sy=j;
}
//记录出口位置
if(migong[i][j]=='G'){
gx=i;gy=j;
}
}
cout<<bfs()<<endl;
}
运行结果如下: