欢迎光临
我们一直在努力

图论最短路径算法精讲

好的,我们来深入浅出地讲解图的最短路径算法及其C++实现。最短路径问题在图论中至关重要,主要分为两类:

  • 单源最短路径:从一个源点到所有其他点的最短路径
  • 多源最短路径:图中任意两点间的最短路径
  • 下面介绍两个经典算法:


    🚀 一、Dijkstra算法(单源最短路径,适用于非负权图)

    核心思想:贪心策略 + 广度优先搜索
    时间复杂度:$O((V+E)\\log V)$(使用优先队列优化)

    📌 算法步骤
  • 初始化距离数组 dist,源点设为0,其余设为无穷大
  • 将源点加入优先队列(小顶堆),按距离排序
  • 循环直到队列空:
    • 取出当前最小距离节点 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算法

    通过代码示例和原理分析,希望您能更直观地理解这两个经典算法的实现精髓! 🚀

    赞(0)
    未经允许不得转载:171主机测评 » 图论最短路径算法精讲
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址