📅  最后修改于: 2023-12-03 15:39:55.249000             🧑  作者: Mango
本题是关于图的最短路径问题,需要用到 Dijkstra 算法。
Dijkstra 算法是一种用于解决图的单源最短路径问题的贪心算法,其基本思想是利用一个集合 S 存储已经求出最短路径的顶点,初始时集合 S 中只包含源点,之后每次从不属于 S 的点中选取一个离源点最近的点加入 S,然后以这个点为中间点更新起点到其它点的距离。
Dijkstra 算法的实现需要使用到优先队列(Priority Queue),优先队列可以保证每次从队列中取出的元素都是未确定最短路径的顶点中距离最小的放顶点。在本题中,我们可以使用 STL 中的 priority_queue。
Dijkstra 算法的时间复杂度为 O(ElogV),其中 E 表示边的数量,V 表示点的数量。
本题中给出了一个有向无环图,源点为 1,我们需要求出源点到其它点的最短路径。由于图是有向无环图,我们可以使用拓扑排序对图进行排序,排序后按拓扑排序的顺序依次使用 Dijkstra 算法求解最短路径。
在具体实现时,我们可以先使用 Kahn 算法求出拓扑排序,然后按照拓扑排序的顺序依次使用 Dijkstra 算法求解最短路径即可。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int main() {
int t, n, m, u, v, w;
cin >> t;
while (t--) {
cin >> n >> m;
vector<int> d(n + 1, INF);
vector<vector<pair<int, int>>> adj(n + 1);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
for (int i = 0; i < m; i++) {
cin >> u >> v >> w;
adj[u].push_back(make_pair(v, w));
}
pq.push(make_pair(0, 1));
d[1] = 0;
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
for (auto edge : adj[u]) {
int v = edge.first;
int w = edge.second;
if (d[v] > d[u] + w) {
d[v] = d[u] + w;
pq.push(make_pair(d[v], v));
}
}
}
for (int i = 2; i <= n; i++) {
cout << d[i] << " ";
}
cout << endl;
}
return 0;
}
首先读入测试数据的数量,之后对于每组数据,我们读入点的数量和边的数量,并存储图的信息。接着使用 priority_queue 存储未确定最短路径的顶点,按照 Dijkstra 算法的过程不断更新 d 数组,最终输出源点到其它点的最短路径。