📜  Dijkstra 的最短路径算法使用 STL 的 priority_queue(1)

📅  最后修改于: 2023-12-03 15:00:24.901000             🧑  作者: Mango

Dijkstra 的最短路径算法使用 STL 的 priority_queue

简介

Dijkstra 算法是一种求解带权图的最短路径的算法。该算法使用贪心策略,在每次找到当前距离最短的结点并标记后,在下一次寻找最短距离的结点时就不会再回到已经找到最短距离的结点了。这样每次找到的最短路径就是最终结果。

实现过程

使用 C++,可以使用标准模板库(STL)中的 priority_queue 来实现。

  • 先定义一个距离数组 dist 保存源点到各顶点的距离,初始时为 INF(无穷大)。
  • 将源点和距离(0)加入 priority_queue(最大堆)。
  • 当堆非空时,取出堆顶元素,如果该元素到源点的距离已经确定,则跳过,否则更新该元素到源点的距离,并将其相邻的未确定最短距离的元素加入堆中。
  • 重复 3 步骤,直到堆为空或到达目标点。
代码实现
#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 5;
int dist[MAXN], head[MAXN], to[MAXN << 1], nxt[MAXN << 1], wei[MAXN << 1], cnt;

void add(int u, int v, int w) {
    to[++cnt] = v;
    nxt[cnt] = head[u];
    head[u] = cnt;
    wei[cnt] = w;
}

void dijkstra(int s) {
    fill(dist, dist + MAXN, INF);
    priority_queue<pair<int, int>> q;
    q.push({0, s});
    dist[s] = 0;
    while (!q.empty()) {
        int u = q.top().second;
        q.pop();
        if (dist[u] == INF) break;
        for (int i = head[u]; ~i; i = nxt[i]) {
            int v = to[i], w = wei[i];
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                q.push({-dist[v], v});
            }
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    memset(head, -1, sizeof(head));
    cnt = -1;

    // TODO: 添加边

    dijkstra(1);

    return 0;
}
优化
  • 如果图为稠密图,可以使用邻接矩阵代替邻接表。这样在查找相邻边时会更快,但是缺点是会消耗更多的空间。
  • 利用小根堆减少堆中元素的次数。
总结

Dijkstra 的最短路径算法实现简单,同时使用 STL 中的 priority_queue 相对较为易于实现。但是需要注意的是,如果图为稠密图,则使用邻接表的效率相对较低。