📜  在 STL 中使用集合的 Dijkstra 最短路径算法(1)

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

在 STL 中使用集合的 Dijkstra 最短路径算法

Dijkstra 最短路径算法是一种用于在加权图中找到从一个节点到另一个节点的最短路径的算法。在本文中,我们将介绍如何在 C++ STL 中使用集合实现 Dijkstra 最短路径算法。

实现
输入格式

假设我们有一个加权有向图,用邻接列表表示。其中,每个节点对应一个整数,这个整数表示节点的编号。我们假设节点的编号从 0 开始,到 N-1 结束,其中 N 表示节点的总数。邻接列表用 vector<vector<pair<int, int>>> 表示,其中第 i 个元素表示节点 i 的出边列表,每个出边用一个 pair 表示,第一个元素表示边的终点节点的编号,第二个元素表示边的权值。

我们还需要向 Dijkstra 算法提供两个参数:起点节点 S 和终点节点 T。这些参数的值是从命令行读入的。

以下代码片段是一个示例输入:

int N, M;
cin >> N >> M >> S >> T;

vector<vector<pair<int, int>>> adj(N);
for (int i = 0; i < M; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    adj[u].push_back({v, w});
}
数据结构

Dijkstra 算法使用了一个距离数组 dis[],其中 dis[i] 表示从起点 S 到节点 i 的距离,如果起点 S 无法到达节点 i,则 dis[i] = INT_MAX。dis[] 数组初始化为 INT_MAX,除了 S 的值为 0。

我们还需要使用一个集合 Q,用于存储未处理的节点。节点 i 在集合 Q 中表示为一个 pair(i, dis[i]),第一个元素表示节点的编号,第二个元素表示从起点 S 到节点 i 的距离。

以下代码片段是用于初始化 dis[] 和 Q 的示例代码:

vector<int> dis(N, INT_MAX);
dis[S] = 0;

set<pair<int, int>> Q;
Q.insert({S, 0});
运行算法

在 Dijkstra 算法的主循环中,我们需要从集合 Q 中找到 dis[] 最小的节点 u,然后遍历节点 u 的出边,更新由这些出边到达的节点的 dis[] 值。更新 dis[] 值后,我们需要更新 Q 中对应的 pair(i, dis[i]) 的值,以确保集合 Q 中的节点排列顺序为 dis[] 值的递增顺序。

重复执行上述操作,直到集合 Q 为空或者找到终点节点 T。最后的 dis[T] 即为起点 S 到终点 T 的最短路径。

以下代码片段是实现 Dijkstra 算法的示例代码:

while (!Q.empty()) {
    int u = Q.begin()->first;
    Q.erase({u, dis[u]});
    for (auto [v, w] : adj[u]) {
        if (dis[v] > dis[u] + w) {
            Q.erase({v, dis[v]});
            dis[v] = dis[u] + w;
            Q.insert({v, dis[v]});
        }
    }
    if (u == T) {
        break;
    }
}
总结

本文介绍了如何在 C++ STL 中使用集合实现 Dijkstra 最短路径算法。由于 STL 自带了集合和 pair 数据结构,实现起来非常简洁高效。实际应用中,还需根据具体问题修改和扩展算法。