BFS:Breadth First Search
搜索算法的一种。从初始结点开始,应用算符生成第一层结点,检查目标结点是否在这些后继结点中,若没有,再用产生式规则将所有第一层的结点逐一扩展,得到第二层结点,并逐一检查第二层结点中是否包含目标结点。若没有,再用算符逐一扩展第二层所有结点……,如此依次扩展,直到发现目标结点为止 。
总结:
1.先搜索距离初始状态近的状态;
2.复杂度为O(状态数×转移方式)
3.广搜运用了队列,搜索的时候首先将初始状态加入队列里,此后从队列的最前端取出状态,把从该状态可以转移到的且尚未访问过的部分加入队列,如此往复,直至队列被取空或找到了问题的解;
4.适用于找最短路径,最少操作数。
队列编程模板:
BFS()
{
Queue<> q;
q.push(i);// 起始点
while(!q.empty())
{
j=q.front();q.pop();
visit(j);
foreach(j子节点k)
{ q.push(k);}
}
}
Q:
迷宫最短路径
给定一个大小为N*M的迷宫,已知迷宫由通道’.’和墙壁’#’组成,S表示主角位置,G代表迷宫出口,主角每一步可移动到上下左右中不是墙壁的位置。请算出主角走到出口的最小步数。(假定迷宫是有解的)(N,M<=100)
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int MAX_N = 100;
const int MAX_M = 100;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> P;
char maze[MAX_N][MAX_M + 1];
int N, M;
int sx, sy; //起点
int gx, gy; //终点
int d[MAX_N][MAX_M];//储存起点到某一点的距离
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; //表明每次x和y方向的位移
void bfs()
{
queue<P> que;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
d[i][j] = INF; //初始化所有点的距离为INF
que.push(P(sx, sy));
d[sx][sy] = 0; //从起点出发将距离设为0,并放入队列首端
while (que.size())
{
P p = que.front(); que.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 (0 <= nx&&nx < N && 0 <= ny&&ny < M &&maze[nx][ny] != '#'
&&d[nx][ny] == INF)
{
que.push(P(nx, ny)); //可以移动则设定距离为之前加一,放入队列
d[nx][ny] = d[p.first][p.second] + 1;
}
}
}
}
int main()
{
scanf("%d %d",&N,&M);
for (int n = 0; n < N; n++)
scanf("%s",&maze[n]);
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
{
if (maze[i][j] == 'S')
{
sx = i; sy = j;
}
if (maze[i][j] == 'G')
{
gx = i; gy = j;
}
}
bfs();
printf("%d\n",d[gx][gy]);
return 0;
}
结果截图: