用std::queue实现bfs更安全高效;需入队前检查visited、立即标记已访问;邻接矩阵必须初始化为0;无向图需双向赋值;记录路径须用prev[]数组并初始化为-1;注意起点终点相同、不可达等边界情况。

用 std::queue 实现 BFS 队列逻辑,别手写循环队列
标准库的 std::queue 完全够用,且不易出错。手写数组模拟队列反而容易越界或忘记更新头尾指针,尤其在多路径扩展时易漏判重复访问。
关键点在于:每次从队首取节点后,必须立即标记为已访问(比如写入 visited[]),否则同一节点可能被多次入队——这是最常见导致 TLE 或路径错误的原因。
- 入队前检查
visited[nxt],不是出队后才检查 - 用
std::queue<:pair int>></:pair>存节点和当前距离,避免额外数组查表 - 邻接矩阵中,
graph[u][v] == 1表示存在边;若带权,需改为非零判断并累加权重
邻接矩阵初始化要清零,否则未赋值位置是随机值
int graph[MAX_N][MAX_N] = {} 是安全写法;只写 int graph[MAX_N][MAX_N]; 而不初始化,会导致 BFS 判断边存在时读到垃圾值,误认为有边从而走入非法节点。
尤其当图稀疏、顶点数大时,这个错误极难调试——现象是 BFS 突然跳到某个本不存在的编号节点,然后访问越界或死循环。
- 推荐统一用
memset(graph, 0, sizeof(graph))或 C++11 的= {}初始化 - 如果输入的是无向图,记得双向赋值:
graph[u][v] = graph[v][u] = 1 - 起点到自身的距离应设为 0,但通常不加入队列(除非题目允许停留)
记录最短路径不能只存距离,得用 prev[] 数组回溯
BFS 本身能保证首次到达某节点的距离是最短的,但若题目要求输出路径(如节点序列),仅靠 dist[] 不够。必须在入队时同步记录前驱:prev[nxt] = curr。
注意:前驱数组初始化为 -1,否则无法区分“未访问”和“起始点前驱”。回溯时从终点倒推,用栈或 vector 反转即可输出正向路径。
- 不要在 BFS 过程中拼接字符串路径,会严重拖慢性能
- 若只需长度,
dist[]足够;若需路径,prev[]必不可少 - 多个终点?BFS 天然支持——遇到任一目标即返回,无需改逻辑
边界情况:起点等于终点、无路径、孤立节点
这些情况不处理,程序可能输出 0(正确)、-1(未初始化 dist)、或直接崩溃(访问 prev[-1])。务必显式覆盖:
- 起点 == 终点:直接返回 0 或路径
{start} - 终点从未入队(
dist[end] == -1):说明不可达,按题意返回 -1 或空路径 - 邻接矩阵全零时,所有
dist[i](i ≠ start)保持初始值,需提前检查
真正容易被忽略的,是图中存在自环(graph[i][i] == 1)或重边——邻接矩阵天然去重,但若手动建图时重复添加,会导致同一条边被多次判断,不过不影响 BFS 正确性,只略微降低效率。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











