c++如何实现迪杰斯特拉最短路径算法_c++ 优先队列优化与邻接表【详解】
发布时间 - 2026-01-21 00:00:00 点击率:次Dijkstra必须用priority_queue配合邻接表以达O((V+E)log V)复杂度;优先队列保证取最小距离节点为O(log V),邻接表确保只遍历真实存在的边;需接受重复入队并跳过过期节点。
为什么 dijkstra 一定要用 priority_queue 配合邻接表?
不用优先队列的朴素 dijkstra 时间复杂度是 O(V²),对点数超 10⁴ 的图基本不可用;而用 std::priority_queue + 邻接表可压到 O((V+E) log V)。关键在于:每次取最小距离节点必须是 O(log V),且只遍历真实存在的边(邻接表保证 E 级别访问),不是全扫数组。
常见错误是把 priority_queue 当成“自动更新堆顶”的容器——它不支持修改已有元素的值,所以必须接受重复入队:当发现更短路径时,直接 push 新二元组 {dist, node},旧的会在后续被 pop 时跳过(靠 if (dist[node] 过滤)。
priority_queue 的比较规则怎么写才不翻车?
C++ 默认是大根堆,但我们要的是“距离最小的先出”,所以必须自定义比较器。最稳妥写法是用仿函数或 lambda,且注意:不能直接写 greater,因为 pair 比较先比 first,而我们希望 first 是距离,所以要让小距离排前面——即“less”语义,但 priority_queue 的模板参数是“谁该被优先弹出”,所以实际要传入「大于」逻辑(即当 a > b 时,a 应该后出,b 先出)。
- 推荐写法:
priority_queue
, vector >, greater >> pq; - 等价但更清晰的 lambda 写法(C++11+):
auto cmp = [](const pair
& a, const pair & b) { return a.first > b.first; };
priority_queue, vector >, decltype(cmp)> pq(cmp); - 错误示范:
priority_queue(大根堆,会先弹出最大距离)>
邻接表怎么建?vector>> 还是 vector>
?
- >
用 vector 是最常用且高效的选择:第一维是起点编号,第二维每个 pair 表示一条有向边(无向图就双向加)。它缓存友好、随机访问快、构造简单。除非边数极少且频繁删边,否则别用 list 或 map。
注意权重类型:如果题目给的是非负整数,用 int;若可能超 INT_MAX 或含浮点,需统一换成 long long 或 double,并同步改 dist 数组和 priority_queue 中的类型。
建边示例(无向图):
vector>> graph(n);
// 加边 u->v 权重 w
graph[u].emplace_back(v, w);
graph[v].emplace_back(u, w);
初始化、松弛、跳过失效节点这三步最容易漏哪?
三个关键动作必须严格按序,缺一不可:
- 初始化:
dist数组全设为INT_MAX(或LLONG_MAX),dist[src] = 0,然后pq.push({0, src}) - 松弛:对当前节点
u的每条出边(u→v, w),若dist[u]
+ w ,则更新
dist[v]并pq.push({dist[v], v}) - 跳过失效节点:在
while (!pq.empty())循环开头,auto [d, u] = pq.top(); pq.pop(); if (d > dist[u]) continue;—— 这行不能省,否则会处理过期状态,导致结果错误或超时
特别注意:dist 数组必须是全局可见的(比如函数内 vector),不能用局部临时变量覆盖;且所有涉及距离比较的地方,类型必须与 dist 一致,避免隐式转换截断。
真正卡住人的往往不是算法逻辑,而是类型不匹配、堆比较器反了、或者忘了跳过过期节点——这三处任一出错,结果就完全不对,还很难 debug。
# node
# ai
# c++
# 隐式转换
# 为什么
# less
# if
# while
# auto
# continue
# int
# double
# 循环
# Lambda
# 堆
# map
# 算法
# 跳过
# 遍历
# 弹出
# 这三
# 的是
# 很难
# 浮点
# 已有
# 设为
# 会在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
郑州企业网站制作公司,郑州招聘网站有哪些?
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
如何安全更换建站之星模板并保留数据?
Laravel如何处理异常和错误?(Handler示例)
Laravel如何升级到最新版本?(升级指南和步骤)
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
北京专业网站制作设计师招聘,北京白云观官方网站?
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
Laravel如何处理表单验证?(Requests代码示例)
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
深入理解Android中的xmlns:tools属性
如何获取免费开源的自助建站系统源码?
javascript如何操作浏览器历史记录_怎样实现无刷新导航
EditPlus中的正则表达式 实战(1)
,在苏州找工作,上哪个网站比较好?
网站图片在线制作软件,怎么在图片上做链接?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
如何快速搭建个人网站并优化SEO?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
Laravel如何与Inertia.js和Vue/React构建现代单页应用
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
米侠浏览器网页背景异常怎么办 米侠显示修复
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
Laravel如何使用Sanctum进行API认证?(SPA实战)
如何用好域名打造高点击率的自主建站?
Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
Laravel如何创建自定义中间件?(Middleware代码示例)
如何快速生成高效建站系统源代码?
使用C语言编写圣诞表白程序
Python数据仓库与ETL构建实战_Airflow调度流程详解
如何用wdcp快速搭建高效网站?
潮流网站制作头像软件下载,适合母子的网名有哪些?
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
Laravel如何实现文件上传和存储?(本地与S3配置)
,网页ppt怎么弄成自己的ppt?
如何用腾讯建站主机快速创建免费网站?
如何在IIS7上新建站点并设置安全权限?
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
公司门户网站制作流程,华为官网怎么做?


