宽度优先搜索
核心是按照距开始状态由近及远的顺序进行搜索,即先找完第一步的情况,再找完第二步的情况,再找完第三步的情况……
所以,可以很容易地找到最短路径,最少操作之类的问题的答案。
例题:
样例答案是22
代码:
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
const int INF=100000000;
typedef pair<int, int>P;
char maze[100][100];
int N,M;
int sx,sy,gx,gy;
int d[100][100];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int bfs()
{
queue<P> que;
int nx,ny;
for(int i=0;i<N;i++)
for(int j=0;j<M;j++) d[i][j]=INF;
que.push(P(sx,sy));
d[sx][sy]=0;
while(que.size())
{
//用大P来定义小p,即小p存放的是一对横纵坐标,que存的也是横纵坐标
P p=que.front();
que.pop(); //取出队列最前端的元素
if(p.first==gx && p.second==gy) break; //能够到达就break;
for(int i=0;i<4;i++)
{
nx=p.first+dx[i],ny=p.second+dy[i];
if(0<=nx&&nx<N &&0<=ny&&ny<M&&maze[nx][ny]!='#'&&d[nx][ny]==INF)
{
que.push(P(nx,ny)); //注意是大P
d[nx][ny]=d[p.first][p.second]+1;
}
}
}
return d[gx][gy];
}
int main()
{
// freopen("a.txt","r",stdin);
int i,j,res;
scanf("%d%d%d%d%d%d",&N,&M,&sx,&sy,&gx,&gy);
for(i=0;i<N;i++) scanf("%s",maze[i]);
res=bfs();
cout<<res;
}
其中:
maze数组用来记录迷宫
d数组用来记录起点到当前坐标的距离,d[2][4]即起点到位置(2,4)走了多少步
dx和dy 是用来控制四方位:
dx[0],dy[0] 即(1,0),意为向右走一步
dx[1],dy[1] 即(0,1),意为向下走一步
dx[2],dy[2] 即(-1,0),意为向左走一步
dx[3],dy[3] 即(0,-1),意为向上走一步
typedef pair<int, int> P; //用来记录横纵坐标
代码的思路是:
先把起点加入队列,然后每次while,记录队列的最前面的元素(记为小p)后,取出,代表当前状态开始搜索。然后从当前元素(小p)的四个方向搜索 不越界 且 不是墙 且 没有走过 的位置,这些位置就可以走动。把可以走动的位置加入队列,然后记录可以走的位置到起点的距离,它们都是比当前位置(p)距离多1。
队列每一个轮回,每条路径都走1步,有的路径走到头,没有可以走动的位置,就不加入队列;有的路径只有一步可走,便只加入一次队列;有的路径遇到分岔路口,便多次加入队列,即一条路径发展出多条路径,且他们的步数一致。
总结:
整个程序下来,统计出1步能到达的位置,且是否到达终点,没有的话统计2步能到达的位置,如果还没有一条路径到达终点,则统计3步能到达的位置……
如此下来就能求出抵达终点的最短路径。