讲师中心 微信公众号

工具推荐

视频效率加速
剧云
剧云

中文短剧剧本制作平台

立刻MV
立刻MV

低成本歌曲 MV、视频生成

AniShort
AniShort

AI短剧协同制作平台

updream

一键生成高质量推广成片

c++中如何实现迪杰斯特拉算法_c++ Dijkstra最短路径算法详解

冬杰大大_2638

冬杰大大_2638

发布时间:2026-01-21 12:51:10

|

444人浏览过

|

来源于php中文网

原创

std::priority_queue不支持堆内元素修改,更新距离后需push新节点并跳过过时条目;邻接表推荐vector;Dijkstra不适用于负权边,应改用Bellman-Ford或SPFA。

c++中如何实现迪杰斯特拉算法_c++ dijkstra最短路径算法详解

用 std::priority_queue 实现 Dijkstra 时为什么距离更新后队列不自动排序

因为 std::priority_queue 不支持堆内元素修改,插入后无法调整位置。常见错误是:发现更短距离时直接 push 新节点,却不标记旧节点失效——导致后续重复处理过时的高代价路径。

  • 必须配合一个 dist[] 数组实时记录当前已知最短距离
  • 每次从堆中 pop 出节点时,先检查 dist[u] != 当前弹出的距离,若不等说明已过时,直接跳过
  • 不要尝试用 make_heap 手动重排队列——开销大且易错

邻接表建图该用 vector<pair int>></pair> 还是 vector<vector int>>></vector>

推荐后者:vector<vector int>>&gt graph(n)</vector>,其中 graph[u] 存储所有从 u 出发的边,pair<int int></int> 表示 {v, weight}(终点与权重)。

  • 前者(单个 vector<pair></pair>)只能表达全局边集,无法快速枚举某点的邻接点,Dijkstra 中每轮需遍历所有边,时间退化为 O(EV)
  • 后者支持 O(degree(u)) 遍历邻居,总复杂度保持 O((V + E) log V)
  • 若图稀疏(E ≈ V),空间也更紧凑;稠密图可考虑邻接矩阵,但仅限 V

遇到负权边就崩?不是说 Dijkstra 不能处理负权吗

是的,标准 Dijkstra 在存在负权边时结果不可靠——它依赖“已确定最短距的节点不会再被更新”这一前提,而负权边会破坏该性质。

Blog for Agents for Knowledge Sharing
Blog for Agents for Knowledge Sharing

在 AgentBlog(blog.agentloka.ai)上作为已认证 AI 代理发布博客文章,支持发布、编辑、删除、评论、浏览和阅读长篇内容。

下载
  • 若你发现算法输出路径比实际长,或 dist[v] 在后期又被更小值覆盖,大概率是输入含负权边
  • 此时应换用 Bellman-Ford(支持负权、可检测负环)或 SPFA(Bellman-Ford 的队列优化版)
  • 注意:负权环存在时,最短路无定义;Dijkstra 对此完全无感知,也不会报错,只会静默给出错误结果

C++ 完整可运行的 Dijkstra 实现(带注释)

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

struct Edge {
    int to, w;
};

vector<long long> dijkstra(int n, const vector<vector<Edge>>& graph, int start) {
    vector<long long> dist(n, LLONG_MAX);
    dist[start] = 0;
    // 小顶堆:{距离, 节点}
    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>& pq;
    pq.push({0, start});

    while (!pq.empty()) {
        auto [d, u] = pq.top(); pq.pop();
        if (d > dist[u]) continue; // 过时条目,跳过
        for (auto& e : graph[u]) {
            int v = e.to;
            long long new_dist = dist[u] + e.w;
            if (new_dist < dist[v]) {
                dist[v] = new_dist;
                pq.push({new_dist, v});
            }
        }
    }
    return dist;
}

int main() {
    int n = 4, m = 5, s = 0;
    vector<vector<Edge>&gt graph(n);
    // 添加边:u->v 权重 w
    graph[0].push_back({1, 1});
    graph[0].push_back({2, 4});
    graph[1].push_back({2, 2});
    graph[1].push_back({3, 6});
    graph[2].push_back({3, 3});

    auto res = dijkstra(n, graph, s);
    for (int i = 0; i < n; ++i)
        cout << "dist[" << i << "] = " << res[i] << "\n";
}

注意 dist 类型用 long long 防止松弛时溢出;LLONG_MAX 是初始化哨兵值,比较时别用 == 判未访问——应统一用 或 <code>> 比较距离大小。图中节点编号从 0 开始是多数竞赛和库的默认习惯,别在索引上 off-by-one。

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

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

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

7539

2023.08.02

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

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

3585

2024.08.29

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

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

4728

2025.08.29

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

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

3145

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

7027

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2888

2023.08.10

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

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

7116

2023.08.14

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

40

2026.11.12

Go-Zero安装与goctl环境配置教程
Go-Zero安装与goctl环境配置教程

本专题围绕Go-Zero的安装与工具链配置展开,讲清Go版本要求、goctl安装方式、代理镜像、protoc依赖与环境变量设置,说明多版本共存、升级回退与CI流水线安装的做法,并整理安装阶段的常见报错与验证步骤。

40

2026.11.12

热门下载

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

精品课程

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn