BFS,由一个点开始,按照层次的顺序向外扩散。
先将起点加入队列;
每次迭代取出队头,再将队头的所有后继加入队列;
迭代至队列为空,则所有点都被搜到。
图示:
例题1.迷宫
给定一个01矩阵(n*m),0表示通路,1表示障碍,求从左上角走到右下角最少需要多少步(题目保证有解)。
数据范围:
1<=n,m<=100。
输入格式:
第一行包含两个整数 n 和 m;
接下来 n 行,每行包含 m个整数(0 或 1),表示完整的二维数组迷宫。
输出格式:
一个数,表示最少步数。
将坐标存入pair中,将每个pair看做一个节点进行BFS即可。
代码如下:
#include<iostream>
#include<queue>
//define x,y,方便取出pair里的坐标
#define x first
#define y second
using namespace std;
typedef pair<int, int>PII;//坐标
const int N = 110;
int g[N][N];//迷宫
bool st[N][N];//状态数组,表示该点搜过没有
int d[N][N];//距离起点的距离
int n, m;
int bfs(PII s, PII e) {
queue<PII>q;//定义队列
q.push(s);//将起点入队
int dx[] = { 0,1,0,-1 }, dy[] = { 1,0,-1,0 };//偏移量
while (q.size()) {//队列不空
//取出队头
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {//往下扩散
int a = dx[i] + t.x,b = dy[i] + t.y;
if (g[a][b] == 1)continue;//如果是走不通
if (st[a][b])continue;//如果搜过了
if (a < 0 || a >= n || b < 0 || b >= m)continue;//如果越界了
//搜到(a,b)
st[a][b] = true;
d[a][b] = d[t.x][t.y] + 1;
q.push({ a,b });//将(a,b)入队
if (make_pair(a,b) == e)return d[a][b];//如果(a,b)是答案
}
}
return -1;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++)//读入迷宫
for (int j = 0; j < m; j++)cin >> g[i][j];
PII start={0,0}, end={n-1,m-1};//从(0,0)走到(n-1,m-1)
cout<<bfs(start, end);//bfs
return 0;
}
若需要求出最短路径,则记录下每个点的前驱,最后通过终点往前推就可推出路径。
注意点:
该BFS代码中,判断当前状态是否为目标状态的代码设置在迭代出新状态之后,所以注意特判起始状态是否就是为目标状态,以免漏掉该情况。