好的,我们来深入浅出地讲解图的最短路径算法及其C++实现。最短路径问题在图论中至关重要,主要分为两类:
下面介绍两个经典算法:
🚀 一、Dijkstra算法(单源最短路径,适用于非负权图)
核心思想:贪心策略 + 广度优先搜索
时间复杂度:$O((V+E)\\log V)$(使用优先队列优化)
📌 算法步骤
- 取出当前最小距离节点 u
- 遍历 u 的邻接点 v:
- 若 dist[u] + w(u,v) < dist[v],则更新 dist[v]
- 将 v 加入队列
⚙️ C++实现(邻接表)
#include <vector>
#include <queue>
#include <climits>
using namespace std;
typedef pair<int, int> pii; // {距离, 节点}
vector<int> dijkstra(vector<vector<pii>>& graph, int start) {
int n = graph.size();
vector<int> dist(n, INT_MAX);
dist[start] =raph.size();
vector<int> dist(n, INT_MAX);
dist[start] = 0;
priority_queue<pii, vector<pii>, greater<pii>> pq;
pq.push({0, start});
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (d > dist[u]) continue; // 跳过旧数据
for (auto& [v, weight] : graph[u]) {
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
pq.push({dist[v], v});
}
}
}
return dist;
}
https://weibo.com/tv/show/1034:5272933116084249
https://weibo.com/tv/show/1034:5272933116084249/
https://weibo.com/tv/show/1034:5272933036392459
https://weibo.com/tv/show/1034:5272933036392459/
https://weibo.com/tv/show/1034:5272932956700694
https://weibo.com/tv/show/1034:5272932956700694/
https://weibo.com/tv/show/1034:5272932889591817
https://weibo.com/tv/show/1034:5272932889591817/
https://weibo.com/tv/show/1034:5272932801249304
https://weibo.com/tv/show/1034:5272932801249304/
🌐 二、Floyd-Warshall算法(多源最短路径)
核心思想:动态规划
时间复杂度:$O(V^3)$
适用场景:稠密图或需要所有点对距离
📌 算法原理
通过中间节点 $k$ 松弛路径:
$$dist[i][j] = \\min(dist[i][j], \\dist[i][k] + dist[k][j])$$
⚙️ C++实现(邻接矩阵)
vector<vector<int>> floyd(vector<vector<int>>& graph) {
int n = graph.size();
auto dist = graph; // 拷贝初始图
for (int k = 0; k < n; ++k)
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX)
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
return dist;
}
https://weibo.com/tv/show/1034:5272933116084249
https://weibo.com/tv/show/1034:5272933116084249/
https://weibo.com/tv/show/1034:5272933036392459
https://weibo.com/tv/show/1034:5272933036392459/
https://weibo.com/tv/show/1034:5272932956700694
https://weibo.com/tv/show/1034:5272932956700694/
https://weibo.com/tv/show/1034:5272932889591817
https://weibo.com/tv/show/1034:5272932889591817/
https://weibo.com/tv/show/1034:5272932801249304
https://weibo.com/tv/show/1034:5272932801249304/
🧠 关键点总结
| Dijkstra | 单源 | $\\geq 0$ | $O(V \\log V)$ | 非负权稀疏图 |
| Floyd | 多源 | 任意* | $O(V^3)$ | 小规模图或多源需求 |
*注:Floyd可处理负权但不可有负权环
实际应用中:
- 导航系统常用Dijkstra/A*算法
- 网络路由分析常用Floyd或Johnson算法
通过代码示例和原理分析,希望您能更直观地理解这两个经典算法的实现精髓! 🚀