思路注:该算法也可以通过P4779 【模板】单源最短路径(标准版)
题中节点 n n n个数的数据级为 1 0 4 10^4 104,边 m m m的个数的数量级为 1 0 5 10^5 105,由数据范围反推算法,可以知道我们应该选择堆优化版的 D i j k s t r a Dijkstra Dijkstra算法来解题,因为该算法的时间复杂度为 O ( m × l o g 2 n ) O(m times log_2n) O(m×log2n),很匹配不是吗hh。所以直接默写板子就好了。
c++代码#include#include #include #include #include using namespace std; const int N = 10010, M = 500010, INF = 0x3f3f3f3f; typedef pair PII; int n, m, s; int h[N], e[M], ne[M], w[M], idx; int dist[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++; } void dijkstra() { memset(dist, 0x3f, sizeof dist); dist[s] = 0; priority_queue , greater > heap; // {距离, 节点的编号} heap.push({0, s}); while(heap.size()) { auto t = heap.top(); heap.pop(); int ver = t.second; if(st[ver]) continue; st[ver] = true; for(int i = h[ver]; i != -1; i = ne[i]) { int j = e[i]; if(dist[j] > dist[ver] + w[i]) { dist[j] = dist[ver] + w[i]; heap.push({dist[j], j}); } } } } int main() { scanf("%d%d%d", &n, &m, &s); memset(h, -1, sizeof h); while(m --) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); } dijkstra(); for(int i = 1; i <= n; i ++) { if(dist[i] == INF) cout << INT_MAX << ' '; else cout << dist[i] << ' '; } return 0; }



