跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 图论最短路径算法详解

综述由AI生成C++ 中三种经典的最短路径算法。Dijkstra 算法适用于无负权图的单源最短路径,采用贪心策略;Bellman-Ford 算法可处理含负权边的图,通过多次松弛边检测负权回路;Floyd-Warshall 算法用于求解任意两点间的最短路径,适合稠密图。文中提供了各算法的核心逻辑及 C++ 代码实现示例。

赛博朋克发布于 2026/3/30更新于 2026/5/2731 浏览
C++ 图论最短路径算法详解

一、Dijkstra 算法

最短路径问题是指,从在带权的有向图中从某一顶点出发,找到通往另一顶点的最短路径,'最短'指的是沿路径各边的权值总和最小。

Dijkstra 算法是单源最短路径的经典贪心算法,只能用于没有负权的图。它从起点出发,每次选当前距离最小且未确定最短路径的节点,用它去松弛(更新)所有邻接点的最短路径估计值,标记该节点为'已确定',重复此过程直到所有节点处理完毕,最终得到起点到图中所有节点的最短路径。

// src 是选定的起点,dist 记录起点到各点的最短路径,pPath 记录到每个点的最短路径的前驱顶点下标
void Dijkstra(const V& src, vector<W>& dist, vector<int>& pPath){
 size_t srci = GetVertexIndex(src);
 size_t n = _vertexs.size();
 dist.resize(n, MAX_W);
 pPath.resize(n, -1);
 dist[srci] = 0;
 pPath[srci] = srci;
 // 已经确定最短路径的顶点集合
 vector<bool> S(n, false);
 for (size_t j = 0; j < n; ++j) {
 // 选最短路径顶点且不在 S 更新其他路径
 int u = 0;
 W min = MAX_W;
 for (size_t i = 0; i < n; ++i) {
 if (S[i] == false && dist[i] < min) {
 u = i;
 min = dist[i];
 }
 }
 S[u] = true;
 // 松弛更新 u 连接顶点 v srci->u + u->v < srci->v 更新
 for (size_t v = 0; v < n; ++v) {
 if (S[v] == false && _matrix[u][v] != MAX_W && dist[u] + _matrix[u][v] < dist[v]) {
 dist[v] = dist[u] + _matrix[u][v];
 pPath[v] = u;
 }
 }
 }
}

二、Bellman_Ford 算法

Bellman-Ford 算法能用来解决负权图的单源最短路径问题,但是它的时间复杂度高于 Dijkstra 算法,本质是暴力求解。从起点出发,把图里所有边从头到尾松弛一遍,重复 n 次,就能算出起点到所有点的最短路径;因为任何最短路径最多只经过 n-1 条边。跑完之后再扫一遍所有边,如果还能更新距离,就说明图里有负权回路,最短路径不存在。

bool BellmanFord(const V& src, vector<W>& dist, vector<int>& pPath){
 size_t n = _vertexs.size();
 size_t srci = GetVertexIndex(src);
 // vector<W> dist,记录 srci-其他顶点最短路径权值数组
 dist.resize(n, MAX_W);
 // vector<int> pPath 记录 srci-其他顶点父顶点数组
 pPath.resize(n, -1);
 // 先更新 srci->srci 为缺省值
 dist[srci] = W();
 // 总体最多更新 n 轮
 for (size_t k = 0; k < n; ++k) {
 // i->j 更新松弛
 bool update = false;
 cout << "更新第:" << k << "轮" << endl;
 for (size_t i = 0; i < n; ++i) {
 for (size_t j = 0; j < n; ++j) {
 // srci -> i + i ->j
 if (_matrix[i][j] != MAX_W && dist[i] != MAX_W && dist[i] + _matrix[i][j] < dist[j]) {
 update = true;
 //cout << _vertexs[i] << "->" << _vertexs[j] << ":" << _matrix[i][j] << endl;
 dist[j] = dist[i] + _matrix[i][j];
 pPath[j] = i;
 }
 }
 }
 // 如果这个轮次中没有更新出更短路径,那么后续轮次就不需要再走了
 if (update == false) {
 break;
 }
 }
 // 还能更新就是带负权回路
 for (size_t i = 0; i < n; ++i) {
 for (size_t j = 0; j < n; ++j) {
 // srci -> i + i ->j
 if (_matrix[i][j] != MAX_W && dist[i] + _matrix[i][j] < dist[j]) {
 return false;
 }
 }
 }
 return true;
}

三、Floyd_Warshall 算法

Floyd-Warshall 算法是求任意两点之间最短路径的算法,依次把每个点当作中转点,判断从 i 到 j 是直接走更近,还是经过这个中转点 k 再走更近,不断更新所有点对的最短距离,三层循环跑完就得到全图最短路径。

void FloydWarshall(vector<vector<W>>& vvDist, vector<vector<int>>& vvpPath){
 size_t n = _vertexs.size();
 vvDist.resize(n);
 vvpPath.resize(n);
 // 初始化权值和路径矩阵
 for (size_t i = 0; i < n; ++i) {
 vvDist[i].resize(n, MAX_W);
 vvpPath[i].resize(n, -1);
 }
 // 直接相连的边更新一下
 for (size_t i = 0; i < n; ++i) {
 for (size_t j = 0; j < n; ++j) {
 if (_matrix[i][j] != MAX_W) {
 vvDist[i][j] = _matrix[i][j];
 vvpPath[i][j] = i;
 }
 if (i == j) {
 vvDist[i][j] = W();
 }
 }
 }
 // 最短路径的更新 i-> {其他顶点} ->j
 for (size_t k = 0; k < n; ++k) {
 for (size_t i = 0; i < n; ++i) {
 for (size_t j = 0; j < n; ++j) {
 // k 作为的中间点尝试去更新 i->j 的路径
 if (vvDist[i][k] != MAX_W && vvDist[k][j] != MAX_W && vvDist[i][k] + vvDist[k][j] < vvDist[i][j]) {
 vvDist[i][j] = vvDist[i][k] + vvDist[k][j];
 // 找跟 j 相连的上一个邻接顶点
 // 如果 k->j 直接相连,上一个点就 k,vvpPath[k][j] 存就是 k
 // 如果 k->j 没有直接相连,k->...->x->j,vvpPath[k][j] 存就是 x
 vvpPath[i][j] = vvpPath[k][j];
 }
 }
 }
 }
}

目录

  1. 一、Dijkstra 算法
  2. 二、Bellman_Ford 算法
  3. 三、Floyd_Warshall 算法
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Lostlife2.0 任务系统智能化:LLama-Factory 驱动动态任务生成
  • Ubuntu 22.04 LTS 物理机安装与配置避坑指南
  • AI 基础学习系列:AIGC 从创意到创造
  • 基于 SpringBoot2 与 Vue3 的在线考试系统架构设计
  • Spark 4.0.2 发布与 GitHub Issues 迁移讨论及社区动态
  • 安卓开发面试复盘:6 次挂面后的经验总结与避坑指南
  • Python 依赖漏洞自动扫描工具
  • C++ std::stringstream 详解
  • 通义 DeepResearch 智能体训练全流程解析
  • Web3 开发者入门:从零构建首个 DApp 实战指南
  • AI 调参实战:网格搜索优化详解
  • AI 产品经理入行必备知识梳理
  • Windows 里用 Linux 不卡顿?WSL + cpolar 让跨系统开发变简单
  • OpenClaw 开源 AI 智能体框架:技术架构、部署与安全分析
  • CCF-GESP 2025 年 6 月 C++ 二级真题解析
  • OpenClaw Gateway 连接断开与超时问题排查
  • ClawdBot (OpenClaw) 结合 Discord 机器人部署与配置指南
  • WebRTC 视频编码基础 (VP8/VP9/H.264/AV1)
  • VSCode 扩展工具 Copilot MCP 使用教程
  • 二叉树常见节点操作与统计

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online