- //#include <iostream>
- //#include <vector>
- //#include <queue>
- //#include <iomanip>
- #include <bits/stdc++.h>
- using namespace std;
- const double INF = numeric_limits<double>::max(); // 無限大
- struct Edge {
- int to;
- double weight;
- };
- struct Node {
- int id;
- double dist;
- bool operator>(const Node& other) const {
- return dist > other.dist; // 優先隊列最小堆
- }
- };
- int main() {
- int M, N; // 景點數量 M,單車車道數量 N
- cin >> M >> N;
- int S, T; // 起點 S,終點 T
- cin >> S >> T;
- vector<vector<Edge>> graph(M + 1); // 使用鄰接表儲存圖
- // 讀取車道資訊
- for (int i = 0; i < N; i++) {
- int a, b;
- double d;
- cin >> a >> b >> d;
- graph[a].push_back({b, d});
- graph[b].push_back({a, d}); // 雙向道路
- }
- // **Dijkstra 演算法**
- priority_queue<Node, vector<Node>, greater<Node>> pq;
- vector<double> dist(M + 1, INF);
- dist[S] = 0;
- pq.push({S, 0});
- while (!pq.empty()) {
- Node cur = pq.top();
- pq.pop();
- int u = cur.id;
- double d = cur.dist;
- if (d > dist[u]) continue; // 若當前距離大於已知最短距離,則跳過
- for (const Edge& e : graph[u]) {
- int v = e.to;
- double newDist = dist[u] + e.weight;
- if (newDist < dist[v]) {
- dist[v] = newDist;
- pq.push({v, newDist});
- }
- }
- }
- // **輸出結果**
- cout << fixed << setprecision(1) << dist[T] << endl;
- return 0;
- }
複製代碼 回復 1# may
--------------------------------------------------------
解題思路
輸入處理:
讀取景點數量
M 和車道數量
N。
讀取起點
S 和終點
T。
使用鄰接表來存儲圖的結構(因為邊數
N 可能遠大於點數
M)。
Dijkstra 演算法:
使用 最小堆 (priority_queue) 來優化最短路徑搜尋。
每次從當前最短距離的節點開始,更新其相鄰節點的距離。
當處理完所有可能的路徑後,終點
T 的距離即為答案。
輸出:
若能到達終點
T,則輸出四捨五入到小數點後 1 位的最短距離。
_______________________________________
程式解釋
讀取輸入:
先讀取 景點數量
M 和 車道數量
N。
再讀取 起點
S 和 終點
T。
用 鄰接表 (vector of vectors) 存儲圖的結構,因為
M 最大是 30,但
N 可以到 200,用鄰接表更省空間。
建構圖 (Graph Representation)
讀取每條道路 (a, b, d),並在 graph[a] 和 graph 中加入該邊,因為是雙向道路。
Dijkstra 演算法:
使用最小堆 (priority_queue) 來優化最短路徑計算。
維護距離陣列 dist[],用來記錄從 S 到其他景點的最短距離。
優先隊列存儲 (景點編號, 當前距離),確保每次處理當前最短距離的節點。
若找到更短的路徑,則更新 dist[v],並將 (v, newDist) 放入最小堆。
輸出結果:
cout << fixed << setprecision(1) << dist[T] << endl;
四捨五入到小數點後 1 位。
時間複雜度分析
Dijkstra 演算法 (Priority Queue):
O(NlogM),因為 priority_queue 操作複雜度為
O(logM),最多有
N 條邊需要處理。
最壞情況:
N=200,M=30,最多
200log30≈200×5=1000 次操作,運行時間 極快。
----------------------------------------------------------
測資:
測試範例
輸入 00
6 8
1 6
1 2 10
1 3 15
2 4 12
2 6 15
3 5 10
4 5 2.58
4 6 1
6 5 5
輸出 00
23.0
輸入01
7 9
1 7
1 2 2.1
1 3 6
2 4 4.9
3 4 8
4 5 10.0
4 6 15
5 6 6
5 7 3.14159
6 7 6
輸出 01
20.1
總結
Dijkstra 適合求最短路徑,使用 最小堆 加速查詢。
鄰接表節省空間,適用於 稀疏圖 (邊數比點數多)。
使用 setprecision(1) 來確保輸出格式正確。
這樣,我們就完成了 城市單車旅遊規劃問題! |