c++怎么实现贝尔曼-福特算法_c++ 负权边处理与最短路径计算【案例】
发布时间 - 2026-01-06 00:00:00 点击率:次贝尔曼-福特算法核心是通过n-1轮松弛操作,用所有边逐轮更新最短距离,可处理负权边但无法处理负权环;C++实现需用LLONG_MAX/2初始化、检测更新提前终止,并通过第n轮判断可达负权环。
贝尔曼-福特算法的核心逻辑是什么
贝尔曼-福特算法本质是通过 n-1 轮松弛操作,逐步逼近每个节点到源点的最短距离;它能处理含负权边的图,但不能处理存在负权环的图(否则最短路径无定义)。关键不在于“多轮迭代”,而在于每轮都尝试用所有边更新距离——这保证了即使最远路径需要经过 n-1 条边,也能在第 n-1 轮被收敛。
如何用 C++ 实现标准版 Bellman-Ford
使用 vector 存储边(起点、终点、权重),配合 vector 维护距离数组。注意初始化为 LLONG_MAX / 2(避免后续加法溢出),源点设为 0。
#include#include #include #include using namespace std; vector
bellman_ford(int n, vector >& edges, int src) { vector dist(n, LLONG_MAX / 2); dist[src] = 0; for (int i = 0; i zuojiankuohaophpcn n - 1; ++i) { bool updated = false; for (auto& [u, v, w] : edges) { if (dist[u] != LLONG_MAX / 2 && dist[u] + w zuojiankuohaophpcn dist[v]) { dist[v] = dist[u] + w; updated = true; } } if (!updated) break; // 提前终止 } return dist;}
n是顶点数(编号从0到n-1)- 边列表可含重复或反向边,不影响正确性
- 提前终止条件(
updated == false)对稀疏图很有效,但不能跳过第n-1轮检测负环怎么检测图中是否存在负权环
运行完
n-1轮松弛后,再执行一轮:若任意边仍能更新距离,则说明存在从源点可达的负权环。注意——只检测“从源点出发能到达的负环”,孤立负环不会触发。立即学习“C++免费学习笔记(深入)”;
bool has_negative_cycle(int n, vector>& edges, int src) { vector dist (n, LLONG_MAX / 2); dist[src] = 0;
for (int i = 0; i zuojiankuohaophpcn n - 1; ++i) { for (auto& [u, v, w] : edges) { if (dist[u] != LLONG_MAX / 2 && dist[u] + w zuojiankuohaophpcn dist[v]) { dist[v] = dist[u] + w; } } } // 第 n 轮检测 for (auto& [u, v, w] : edges) { if (dist[u] != LLONG_MAX / 2 && dist[u] + w zuojiankuohaophpcn dist[v]) { return true; } } return false;}
- 必须用同一套
dist数组连续跑n轮,不能重置- 若只需判断负环存在性,无需保存中间距离,可省去提前终止
- 若图不连通,且负环不在源点连通分量内,该函数返回
false——这是预期行为,不是 bug实际使用时最容易踩的坑
负权边本身不危险,危险的是没意识到 Bellman-Ford 的“可达性前提”和整数溢出风险。
- 输入边时忘记检查
u和v是否在[0, n)范围内,导致越界访问- 用
INT_MAX初始化dist,遇到负权边做加法时直接溢出成负数,后续比较全乱- 误以为返回
LLONG_MAX / 2就代表“不可达”,其实应判断是否仍等于初始值(因为负权路径可能真达到极大正值)- 多源点场景下直接复用单源实现,结果只算出一个源点的结果——Bellman-Ford 本就是单源算法,多源需多次调用或改用 Floyd
负权边能算,但得确保你真正需要它;多数业务场景里,出现负权往往意味着建模错误,先确认是不是权重含义理解反了,比急着写松弛更关键。
# edge # c++ # ios # stream # int # 算法 # bug # 源点 # 贝尔 # 福特 # 可达 # 最短 # 标准版 # 的是 # 这是 # 很有 # 只需
相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251811 】 【 AI营销90571 】
相关推荐: Python结构化数据采集_字段抽取解析【教程】 C#如何调用原生C++ COM对象详解 Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】 Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验 高性价比服务器租赁——企业级配置与24小时运维服务 Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】 Python自然语言搜索引擎项目教程_倒排索引查询优化案例 Laravel如何与Pusher实现实时通信?(WebSocket示例) 如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套) EditPlus中的正则表达式 实战(4) 如何在宝塔面板创建新站点? Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】 iOS UIView常见属性方法小结 Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询 夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化 php 三元运算符实例详细介绍 Laravel DB事务怎么使用_Laravel数据库事务回滚操作 如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】 Python数据仓库与ETL构建实战_Airflow调度流程详解 如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些? 如何用AI帮你把自己的生活经历写成一个有趣的故事? 魔方云NAT建站如何实现端口转发? 如何用wdcp快速搭建高效网站? Mybatis 中的insertOrUpdate操作 北京的网站制作公司有哪些,哪个视频网站最好? jquery插件bootstrapValidator表单验证详解 如何用已有域名快速搭建网站? Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解 如何在景安云服务器上绑定域名并配置虚拟主机? Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议 Linux安全能力提升路径_长期防护思维说明【指导】 怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平? 非常酷的网站设计制作软件,酷培ai教育官方网站? iOS正则表达式验证手机号、邮箱、身份证号等 制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站? 高端智能建站公司优选:品牌定制与SEO优化一站式服务 Laravel API资源类怎么用_Laravel API Resource数据转换 打造顶配客厅影院,这份100寸电视推荐名单请查收 成都品牌网站制作公司,成都营业执照年报网上怎么办理? Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出 uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址 iOS验证手机号的正则表达式 laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程 安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出 Internet Explorer官网直接进入 IE浏览器在线体验版网址 如何有效防御Web建站篡改攻击? 在线ppt制作网站有哪些软件,如何把网页的内容做成ppt? Laravel如何实现模型的全局作用域?(Global Scope示例) 如何快速搭建二级域名独立网站? 网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?


(n, LLONG_MAX / 2);
dist[src] = 0;