算法系列 | 图论最短路径算法
目录引入一、经典单源最短路径1.普通BFS代码2.Dijkstra迪杰斯特拉算法代码3.Bellman-Ford代码4.SPFA代码二、多源全源最短路径1.Floyd-Warshall代码2.Johnson代码总结例题基础提高引入这是一张无向图接下来尝试给边上加上一些箭头你就得到了一张有向图在拓展一点给每条边赋予边权你就得到了一张有向带权图我们可以假设边权就是距离那么我们就得到了一张地图。接下来抛出一个问题我们该如何求任意两点或某个确定点与其他点的最短路径呢这时就要用到单/多源最短路径算法也就是本文的主题。最短路径算法有许多通常会根据不同的场景来选择不同的最短路径算法。一、经典单源最短路径单源最短路径指的是求某一个确定的点到其他所有点的最短距离。1.普通BFS常用于无权图所有边权重相等核心思想是逐层向外扩展首次访问即最短路径。代码int dist[MAXN]; int q[MAXN]; // 数组模拟队列 void bfs(int n, int src) { memset(dist, -1, sizeof(dist)); int front 0, rear 0; dist[src] 0; q[rear] src; while (front rear) { int u q[front]; for (int i head[u]; i ! -1; i nxt[i]) { int v to[i]; if (dist[v] -1) { dist[v] dist[u] 1; q[rear] v; } } } }2.Dijkstra迪杰斯特拉算法常用于非负权图是一种贪心算法每次选取离起点最近且未处理的节点进行松弛。通常会使用优先队列优化适合稀疏图。代码#include queue using PII pairint, int; int dist[MAXN]; bool vis[MAXN]; void dijkstra(int n, int src) { memset(dist, 0x3f, sizeof(dist)); memset(vis, false, sizeof(vis)); priority_queuePII, vectorPII, greaterPII pq; dist[src] 0; pq.push({0, src}); while (!pq.empty()) { auto [d, u] pq.top(); pq.pop(); if (vis[u]) continue; vis[u] true; for (int i head[u]; i ! -1; i nxt[i]) { int v to[i], w weight[i]; if (!vis[v] dist[v] dist[u] w) { dist[v] dist[u] w; pq.push({dist[v], v}); } } } }3.Bellman-Ford更适用于非负权稠密图核心思路是对每条边进行轮松弛操作。较少使用。代码struct Edge { int u, v, w; } edges[MAXM]; int dist[MAXN]; bool bellman_ford(int n, int m, int src) { memset(dist, 0x3f, sizeof(dist)); dist[src] 0; // 松弛 n-1 次 for (int i 1; i n - 1; i) { bool updated false; for (int j 1; j m; j) { int u edges[j].u, v edges[j].v, w edges[j].w; if (dist[u] ! INF dist[v] dist[u] w) { dist[v] dist[u] w; updated true; } } if (!updated) break; } // 检测负环 for (int j 1; j m; j) { int u edges[j].u, v edges[j].v, w edges[j].w; if (dist[u] ! INF dist[v] dist[u] w) { return false; // 存在负环 } } return true; }4.SPFA在所有最短路径算法中最“全面发展”的一个但在部分特殊情况不如某些其他算法。核心思路是用队列维护发生松弛的节点减少无效松弛。稀疏图极快但很有可能被出题者卡数据导致退化为。代码int dist[MAXN]; bool inQueue[MAXN]; int q[MAXN]; // 队列 int cnt[MAXN]; // 入队次数检测负环 bool spfa(int n, int src) { memset(dist, 0x3f, sizeof(dist)); memset(inQueue, false, sizeof(inQueue)); memset(cnt, 0, sizeof(cnt)); int front 0, rear 0; dist[src] 0; q[rear] src; inQueue[src] true; while (front rear) { int u q[front]; inQueue[u] false; for (int i head[u]; i ! -1; i nxt[i]) { int v to[i], w weight[i]; if (dist[v] dist[u] w) { dist[v] dist[u] w; if (!inQueue[v]) { q[rear] v; inQueue[v] true; cnt[v]; if (cnt[v] n) return false; // 存在负环 } } } } return true; }二、多源全源最短路径1.Floyd-Warshall通常用邻接矩阵实现更适合稠密图只是时间复杂度有些高核心思想为动态规划枚举中间点尝试松弛的路径。代码int g[MAXN][MAXN]; // 邻接矩阵 void floyd(int n) { // 初始化g[i][i]0, 有边g[i][j]w, 无边g[i][j]INF for (int k 1; k n; k) { for (int i 1; i n; i) { if (g[i][k] INF) continue; // 小优化 for (int j 1; j n; j) { if (g[i][j] g[i][k] g[k][j]) { g[i][j] g[i][k] g[k][j]; } } } } }2.Johnson适合稀疏图核心思想为先通过重新赋予非负权重势能法再对每个点跑。代码int h[MAXN]; // 势能 int dist_johnson[MAXN][MAXN]; // 结果矩阵 bool johnson(int n, int m) { // Step 1: 添加超级源点0到所有点边权为0 for (int i 1; i n; i) { addEdge(0, i, 0); } // Step 2: SPFA/Bellman-Ford 计算势能h[] if (!spfa(n 1, 0)) { return false; // 存在负环 } for (int i 1; i n; i) { h[i] dist[i]; } // Step 3: 移除超级源点重新建图 // 实际使用中重新初始化head重新添加原边这里省略 // 新权重 w w h[u] - h[v] (非负) // Step 4: 对每个点跑Dijkstra for (int src 1; src n; src) { // 使用上面的dijkstra函数使用重新赋权后的图 // 结果 dist_johnson[src][v] dist[v] h[v] - h[src] } return true; }总结首先是对各类最短路径算法的详细汇总算法名称时间复杂度适用场景核心思想能否处理负权图密度适用性BFS广度优先搜索O(V E)无权图所有边权重相等逐层向外扩展首次访问即最短路径。不涉及权重稀疏/稠密均可E较小更优Dijkstra优先队列优化O((VE) log V)非负权图最常用贪心策略每次选取离起点最近且未处理的节点进行松弛。不能负权会失效稀疏图更优ElogVBellman-FordO(VE)含负权边的图对每条边进行 V-1 轮松弛操作。能可检测负环稀疏图尚可稠密图极慢SPFA队列优化Bellman-Ford平均 O(E)最坏 O(VE)含负权边且需快速或判断负环用队列维护发生松弛的节点减少无效松弛。能可检测负环稀疏图极快稠密图易退化Floyd-WarshallO(V³)稠密图或需输出所有点对距离动态规划枚举中间点 k尝试松弛 i→j 的路径。能但不能有负环稠密图最优V³与E无关JohnsonO(VE V² log V)稀疏图且含负权边先通过 Bellman-Ford 重新赋予非负权重势能法再对每个点跑 Dijkstra。能但不能有负环稀疏图更优当 E V²/logV 时其次是对算法选择的决策过程1. 无权图 → BFS单源 / 多源BFS全源 2. 非负权图 ├─ 单源 │ ├─ 稀疏图E V²/logV→ Dijkstra优先队列O(ElogV) │ └─ 稠密图E ≈ V² → Dijkstra朴素O(V²) └─ 全源 ├─ 稀疏图 → 对每个点跑Dijkstra堆O(VElogV) └─ 稠密图 → Floyd-Warshall O(V³) 3. 含负权边无负环 ├─ 单源 │ ├─ 稀疏图 → SPFA平均O(E) │ └─ 稠密图 → Bellman-Ford O(VE) 或 SPFA但都会很慢 └─ 全源 ├─ 稀疏图 → Johnson O(VE V²logV) └─ 稠密图 → Floyd-Warshall O(V³)虽慢但实现简单 4. 需要检测负环 ├─ 单源 → Bellman-Ford 或 SPFA └─ 全源 → Floyd-Warshall检测 g[i][i] 0接下来是对于图的密度的判断标准图类型判断标准说明稀疏图E V log V邻接表存储优先队列Dijkstra中等图V E V² / logV两种Dijkstra都可以稠密图E ≈ V²邻接矩阵存储朴素Dijkstra或Floyd完全图E V(V-1)/2必然用朴素Dijkstra或Floyd例题基础洛谷 P2910 [USACO08OPEN] Clear And Present Danger Shttps://www.luogu.com.cn/problem/P2910洛谷 P3371 【模板】单源最短路径弱化版https://www.luogu.com.cn/problem/P3371提高P1144 最短路计数https://www.luogu.com.cn/problem/P1144P2446 [SDOI2010] 大陆争霸https://www.luogu.com.cn/problem/P2446感谢观看有问题欢迎提出

相关新闻

维修工程师的示波器实战:06 差分探头——真正进入高频世界的大门

维修工程师的示波器实战:06 差分探头——真正进入高频世界的大门

第六篇:差分探头——真正进入高频世界的大门 ——当你终于停止测量“地”,才开始真正测量信号 凌晨两点。 伺服驱动器再次发出刺耳的故障报警。 过压保护频繁触发。 母线电压正常。 电源正常。 控制逻辑正常。 所有参数看起来都“没问题”。 年轻工程师接上普通探头,屏息…

2026/10/20 15:10:59 阅读更多 →
Unity GLB模型导入插件选择与性能优化全攻略

Unity GLB模型导入插件选择与性能优化全攻略

1. 项目概述:为什么GLB模型导入值得你花时间研究?在Unity项目里,尤其是涉及到AR/VR、数字孪生或者高精度可视化展示时,导入外部3D模型是家常便饭。几年前,FBX格式几乎是唯一的选择,但最近几年,G…

2026/10/20 7:02:41 阅读更多 →
2026年正规SEO公司怎么选:七大避坑维度+真实案例复盘+KPI对赌合同指南|解析

2026年正规SEO公司怎么选:七大避坑维度+真实案例复盘+KPI对赌合同指南|解析

核心要点:从投入产出关系看,2026年SEO服务市场良莠不齐,企业筛选正规SEO公司,应围绕资质审查、白帽技术验证、内容质量检查、数据透明度、合同条款、KPI对赌机制以及售后退出安排七个维度展开系统评估。从结果验证看,本…

2026/10/19 7:25:26 阅读更多 →

最新新闻

NLTK情感分析实战:朴素贝叶斯文本分类与特征工程

NLTK情感分析实战:朴素贝叶斯文本分类与特征工程

开头我先交代一个背景。去年我接了一个某售后团队的文本处理需求,他们每个月有近万条用户反馈,需要把表达不满的留言单独捞出来,让客服优先跟进。一开始大家都以为这种“情绪识别”要上什么重磅模型,结果我用了NLTK这套老牌工具&a…

2026/10/20 15:11:55 阅读更多 →
H3C防火墙双机热备:RBM+VRRP原理与Web配置实战

H3C防火墙双机热备:RBM+VRRP原理与Web配置实战

做网络运维这些年,防火墙双机热备是我见过最务实、也最容易被忽视的一项配置。很多朋友一提到RBMVRRP,脑子里就浮现一堆命令行,要么对着文档一行行抄,要么在设备上死记硬背,最后改一个接口就全乱了。其实H3C防火墙这套…

2026/10/20 15:11:55 阅读更多 →
OWASP Benchmark实战:用黄金标准量化评估SAST/DAST工具能力

OWASP Benchmark实战:用黄金标准量化评估SAST/DAST工具能力

如果你负责过应用安全工具选型,大概率经历过这种尴尬:会议室里各家厂商把 SAST、DAST 工具演示得天花乱坠,漏洞检出率动辄宣称百分之九十几,可一旦回到真实业务,漏报和误报依旧扎心。这种局面本质上不是某个工具不行&a…

2026/10/20 15:11:55 阅读更多 →
VS2017编译64位libssh2:OpenSSL与Zlib三库协同实战指南

VS2017编译64位libssh2:OpenSSL与Zlib三库协同实战指南

简介:本资源是面向Windows平台C/C开发者的一站式libssh2 64位编译成果包,专为解决VS2017环境下64位应用程序集成SSH2协议能力的刚需。资源提供已成功编译的完整libssh2 Win64库及配套头文件、依赖DLL(含libcrypto-1_1-x64.dll与libssl-1_1-x6…

2026/10/20 15:11:55 阅读更多 →
路由器工作原理深度拆解:路由表、数据包转发与NAT

路由器工作原理深度拆解:路由表、数据包转发与NAT

上次帮邻居调网络,发现他家的光猫、路由器、交换机全都挤在弱电箱里,线乱成一团。他说自己只会“插上电源,连上Wi-Fi”,至于路由器里面到底干了什么,完全是个黑盒子。这其实是很普遍的现象——路由器天天在用&#xff…

2026/10/20 15:11:55 阅读更多 →
Apple Silicon 虚拟机 EFI_RNG_PROTOCOL 缺失排查

Apple Silicon 虚拟机 EFI_RNG_PROTOCOL 缺失排查

前两天我在一台 M2 的 Mac mini 上用 VMware Fusion 装 Ubuntu 22.04 ARM 版,系统安装完重启,屏幕刷过一长串启动日志,其中一行EFI_RNG_PROTOCOL unavailable特别扎眼。第一反应就是“启动失败了”。结果等了几秒,系统照常进到了登…

2026/10/20 15:10:51 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →