0

0

C++如何实现广度优先搜索BFS_C++图论算法路径查找实例【练习】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-17 17:44:49

|

703人浏览过

|

来源于php中文网

原创

最稳妥的c++ bfs实现是用std::queue管理节点、std::vector记录访问状态;必须“入队即标记”,邻接表按图类型双向/单向建边,路径还原需维护parent数组并正确初始化与回溯。

c++如何实现广度优先搜索bfs_c++图论算法路径查找实例【练习】

std::queuestd::vector 实现标准 BFS 遍历

广度优先搜索在 C++ 中最稳妥的实现方式是依赖 STL 容器:用 std::queue 管理待访问节点,用 std::vector<bool></bool>std::vector<int></int> 记录访问状态或距离。别手写队列,也别用 std::stack 混淆——BFS 的层序特性完全依赖 FIFO 行为。

常见错误是把邻接点一股脑 push 进队列却不标记已入队,导致重复入队、内存爆掉或死循环。正确做法是「入队即标记」,不是「出队才标记」。

  • 初始化时将起点入队,并设 visited[start] = true
  • 每次从队首取节点 u,遍历其所有邻接点 v
  • 对每个未访问过的 v,立刻设 visited[v] = true,再 push 入队
  • 若需记录路径长度,用 dist[v] = dist[u] + 1;若需还原路径,额外维护 parent[v] = u

邻接表建图时注意边方向与重边处理

图的存储方式直接影响 BFS 正确性。无向图要双向加边:adj[u].push_back(v)adj[v].push_back(u) 缺一不可;有向图只加单向边。如果输入含重边(相同 u→v 多次),std::vector 邻接表会存多份,但只要访问标记到位,不影响结果——只是略微拖慢常数。

别用邻接矩阵存稀疏图:10⁵ 节点时 int adj[100000][100000] 直接编译失败或 OOM。真要动态建图,用 vector<vector>></vector> 即可,空间复杂度 O(V+E)。

立即学习C++免费学习笔记(深入)”;

Toolify.ai
Toolify.ai

Toolify.ai是一个专门收集、评测AI工具和服务的网址导航站

下载
  • 输入 N 个节点(编号 0~N-1)和 M 条边,先 vector<vector>> adj(N)</vector>
  • 读入每条边后,按图类型决定是否双向插入
  • 若题目说「可能有自环」,检查 u == v,通常跳过(避免自己访问自己)

从 BFS 到最短路径:如何还原具体路径

BFS 本身只保证首次到达某点时路径最短(无权图),但默认不保存路径细节。要输出从起点到终点的完整节点序列,必须在搜索时记录每个节点的前驱 parent[v]。终点回溯到起点后,再反转数组即可。

容易忽略的是:起点的 parent[start] 应设为 -1 或特殊值,否则回溯时无法终止;另外,若终点根本不可达,parent[end] 保持初始值(如 -1),需提前判断,否则反转空路径会 crash。

  • 声明 vector<int> parent(n, -1)</int>,起点处 parent[start] = -2 或保留 -1 并单独标记
  • 当从 u 扩展到 v 时,执行 parent[v] = u
  • 回溯时用 while (v != -1) { path.push_back(v); v = parent[v]; },最后 reverse(path.begin(), path.end())

遇到超时或 WA?检查这三处硬伤

练习中 80% 的 WA 或 TLE 来自边界疏漏,而非算法逻辑。尤其注意:节点编号是否从 0 开始?输入的边是否包含无效索引(如 N=5 却出现节点 6)?队列是否用了 int 而非 size_t 导致下标越界?

  • 读入节点数 N 后,邻接表大小必须是 adj.resize(N),不是 N+1(除非题目明确编号 1~N 且你习惯偏移)
  • queue 存的是节点编号,不是指针或结构体——别为了“省事”塞 pair<int></int> 却忘了更新逻辑
  • 多组测试用例时,每次都要清空 adj、重置 visitedparent,不能只 memset 部分内存

路径查找类题目的关键不在 BFS 框架,而在建图与回溯的衔接是否干净。一个没初始化的 parent 数组,比算法写错更难调试。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

103

2023.09.25

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

344

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

198

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

572

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

234

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

210

2025.08.29

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

454

2023.08.14

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

283

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.6万人学习

C 教程
C 教程

共75课时 | 4.8万人学习

C++教程
C++教程

共115课时 | 18.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号