BFS 广度优先搜索模板
772 字
4 分钟
BFS 广度优先搜索模板
BFS 广度优先搜索模板
BFS 的全称是 Breadth First Search,也就是广度优先搜索。它最常用的场景是求“最短步数”,比如迷宫从起点走到终点最少需要几步。
BFS 的核心思想可以理解为一圈一圈往外扩展。先处理距离起点为 0 的点,再处理距离为 1 的点,再处理距离为 2 的点,所以第一次到达某个点时,距离一定是最短的。
1、BFS 的基本步骤
1. 创建队列2. 起点入队,并标记已经访问3. 队列不空时,取出队头4. 枚举它能走到的下一个点5. 如果下一个点合法且没有访问过,就更新距离并入队关键点:
- BFS 一般用队列。
- 每个点通常只入队一次。
dist数组可以记录到每个点的最短距离。
2、一维图上的 BFS 模板
queue<int> q;q.push(start);dist[start] = 0;
while (!q.empty()) { int t = q.front(); q.pop();
for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] == -1) { dist[j] = dist[t] + 1; q.push(j); } }}这里 dist[j] == -1 表示节点 j 没有被访问过。
3、迷宫最短路模板
题目场景:
0表示可以走。1表示障碍物。- 从左上角走到右下角。
- 每次只能上下左右移动一格。
#include <bits/stdc++.h>using namespace std;
const int N = 110;
int n, m;int g[N][N];int dista[N][N];pair<int, int> q[N * N];
int bfs() { memset(dista, -1, sizeof dista);
int hh = 0, tt = 0; q[0] = {0, 0}; dista[0][0] = 0;
int dx[4] = {-1, 0, 1, 0}; int 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]; int y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && dista[x][y] == -1) { dista[x][y] = dista[t.first][t.second] + 1; q[++tt] = {x, y}; } } }
return dista[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() << endl; return 0;}4、为什么 BFS 能求最短路
因为 BFS 是按照距离从小到大的顺序扩展的。
比如起点距离是 0,下一层距离是 1,再下一层距离是 2。某个点第一次被访问时,一定是从最短的路径过来的。如果后面还有其他路径到它,那些路径只会更长或者一样长。
5、容易写错的地方
(1)忘记初始化距离数组
memset(dista, -1, sizeof dista);如果不初始化,就无法判断一个点是否访问过。
(2)没有标记起点
dista[0][0] = 0;起点必须先标记,否则可能重复入队。
(3)坐标边界写错
x >= 0 && x < n && y >= 0 && y < m二维数组题最容易错的就是边界。
总结
BFS 模板一定要记住两个东西:
队列 q + 距离数组 dist只要题目问“最少几步”“最短操作次数”“最少转换次数”,第一反应就可以先想 BFS。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!













