[CF20C] Dijkstra? - 最短路
阿新 • • 發佈:2020-12-17
[CF20C] Dijkstra? - 最短路
Description
給出一張圖,請輸出其中任意一條可行的從點 1 到點 n 的最短路徑。
Solution
(當作是複習資料結構,默一遍 Dijkstra 板子)
Dijkstra 的核心思想是維護一個已經處理過的集合 S,每次選擇一個 \(p \notin S\) 的 \(dist[p]\) 最小的 p,將它加入集合 S 中,並且更新所有 p 的直接後繼的距離。
實現中,我們用堆來加速查詢最小值的過程。具體地,我們在小頂堆中壓入 (距離,頂點) 的結構,每次鬆弛操作後都壓入(這樣可能會導致堆中出現重複元素,沒有關係,只要我們通過 \(vis[]\)
#include <bits/stdc++.h> using namespace std; #define int long long signed main() { ios::sync_with_stdio(false); int n; int m; cin >> n >> m; vector<int> vis(n + 2, 0), dis(n + 2, (long long)(1e18)), from(n + 2, 0); vector<tuple<int, int, int>> edges; vector<vector<pair<int, int>>> g(n + 2, vector<pair<int, int>>()); for (int i = 1; i <= m; i++) { int t1, t2, t3; cin >> t1 >> t2 >> t3; edges.emplace_back(make_tuple(t1, t2, t3)); g[t1].emplace_back(make_pair(t2, t3)); g[t2].emplace_back(make_pair(t1, t3)); } priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que; dis[1] = 0; que.push(make_pair(dis[1], 1)); while (!que.empty()) { auto [d, p] = que.top(); que.pop(); if (vis[p]) continue; vis[p] = 1; for (auto [q, w] : g[p]) { if (dis[p] + w < dis[q]) { dis[q] = dis[p] + w; from[q] = p; que.push(make_pair(dis[q], q)); } } } function<void(int)> print = [&](int p) -> void { if (p) { print(from[p]); cout << p << " "; } }; if (dis[n] < 1e17) { print(n); } else { cout << -1; } }