c++怎么实现弗洛伊德算法求最短路径_c++ 动态规划与邻接矩阵更新【案例】
发布时间 - 2026-01-02 00:00:00 点击率:次弗洛伊德算法必须以k为最外层循环,因状态转移依赖disti和distk在当前轮次已被正确更新;初始化需设disti=0、有向边权值、其余为安全INF(如0x3f3f3f3f),并判INF再更新以防溢出。
弗洛伊德算法的核心是三重循环更新 dist[i][j]
它不依赖起点或终点预设,而是穷举所有中间点 k,检查是否通过 k 能让 i → j 更短。关键不是“怎么初始化”,而是“为什么必须按 k 为最外层循环”。如果把 i 或 j 放最外层,dist[i][k] 和 dist[k][j] 可能还没被当前轮次更新过,导致路径拼接失效。
初始化时,dist[i][i] = 0,有向边 (u, v, w) 对应 dist[u][v] = w,其余设为一个足够大的数(如 INT_MAX / 2,避免加法溢出)。
-
INT_MAX直接参与加法易溢出,用INT_MAX / 2更安全 - 图中含负权边可运行,但含负权环时,
dist[i][i]最终会为负 —— 这是检测负环的依据 - 节点编号建议从
0开始,避免数组越界和偏移计算错误
邻接矩阵更新要防止整型溢出和无效路径叠加
核心更新语句是:dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])。但若 dist[i][k] 或 dist[k][j] 仍是初始大值,直接相加会溢出。必须先判断有效性:
if (dist[i][k] != INF && dist[k][j] != INF) {
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
否则哪怕逻辑上不可达,数值上也会因溢出变成极小负数,污染后续结果。
- 不要用
== INT_MAX判断“不可达”,浮点或大数运算后可能失真;统一用自定义常量INF - 更新顺序不能交换:必须是
k在最外层,否则不是 Floyd,而是错误的松弛顺序 - 空间复杂度固定为
O(n²),无法像 Dijkstra 那样用堆优化;适合n ≤ 500的稠密图
动态规划视角下,dist[k][i][j] 的含义容易被误解
教材常说“dist[k][i][j] 表示只允许经过前 k 个节点时 i→j 的最短距离”,但这只是教学抽象。实际代码中根本没存三维数组 —— 它被压缩进二维并复用,靠 k 循环顺序保证状态转移正确。真正发生的是:每轮 k 结束后,dist[i][j] 已包含所有经节点 0..k 的最短路。
- 没有显式维度
k,所以不能在循环中随意访问 “上一轮” 的dist[i][j] - 不能把
dist[i][j]更新写成dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])之外的形式(比如加条件跳过某些k),会破坏 DP 状态定义 - 若需输出路径,得额外维护
next[i][j]记录中转点,每次更新dist时同步更新
常见报错:runtime error: signed integer overflow 或全为 INF
前者几乎全是没判 INF 就做加法;后者常见于输入没读进邻接矩阵(比如节点编号从 1 开始却往 [0][0] 写)、或忘了设 dist[i][i] = 0。还有一种隐蔽错误:用 memset(dist, 0x3f, sizeof dist) 初始化,但 0x3f3f3f3f 是常用 INF 值,而若误写成 0x7f7f7f7f,它接近 INT_MAX,加法极易溢出。
- 推荐初始化方式:
const int INF = 0x3f3f3f3f; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { dist[i][j] = (i == j) ? 0 : INF; } } - 调试时打印几组
dist[0][*]或dist[*][n-1],比看全矩阵更高效 - 算法本身不处理离散节点名(如字符串 ID),必须先映射为
0..n-1整数索引
# c++
# overflow
# 为什么
# Integer
# 常量
# 三维数组
# Error
# 整型
# 字符串
# 循环
# 堆
# 算法
# 弗洛伊德
# 的是
# 最外层
# 可达
# 必须先
# 这是
# 穷举
# 还没
# 也会
# 浮点
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
怎么用AI帮你设计一套个性化的手机App图标?
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
如何快速生成可下载的建站源码工具?
Python制作简易注册登录系统
WEB开发之注册页面验证码倒计时代码的实现
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
英语简历制作免费网站推荐,如何将简历翻译成英文?
详解Huffman编码算法之Java实现
JavaScript如何实现倒计时_时间函数如何精确控制
Laravel定时任务怎么设置_Laravel Crontab调度器配置
微信公众帐号开发教程之图文消息全攻略
如何在宝塔面板创建新站点?
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
高防服务器:AI智能防御DDoS攻击与数据安全保障
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
js实现获取鼠标当前的位置
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
如何批量查询域名的建站时间记录?
javascript中对象的定义、使用以及对象和原型链操作小结
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
如何用腾讯建站主机快速创建免费网站?
,怎么在广州志愿者网站注册?
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
Android 常见的图片加载框架详细介绍
如何制作一个表白网站视频,关于勇敢表白的小标题?
Java解压缩zip - 解压缩多个文件或文件夹实例
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
html5的keygen标签为什么废弃_替代方案说明【解答】
LinuxCD持续部署教程_自动发布与回滚机制
网站建设要注意的标准 促进网站用户好感度!
Laravel如何创建自定义Artisan命令?(代码示例)
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
Android滚轮选择时间控件使用详解
如何在Ubuntu系统下快速搭建WordPress个人网站?
如何在云虚拟主机上快速搭建个人网站?
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
Laravel如何处理异常和错误?(Handler示例)
Android利用动画实现背景逐渐变暗
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
如何快速选择适合个人网站的云服务器配置?
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用
免费视频制作网站,更新又快又好的免费电影网站?
如何基于云服务器快速搭建网站及云盘系统?

