https://leetcode.com/problems/minimum-cost-of-a-path-with-special-roads/
這是一題 SSSP(Single-Source Shortest Path) 問題,第一個想法就是直接用 Dijkstra 解決。但是這題跟其他問題不一樣的地方在於,這個 graph 是無限大的,因爲我們要在二維平面找最短距離,而二維平面沒有邊界。因此,什麼時候要結束 Dijkstra algorithm 變成了新的問題。
首先,從 start 到 target 的最短距離只會有兩種情況,
- 有經過 special road
- 沒有經過 special road
所以只需要找到 start 到各個 special road 的終點的最短距離,最後再看看 start 到 target 的最短距離是多少即可。
同樣地,從 start 到 special road 的終點的最短距離也只會有以上的兩種情況,所以跑 Dijkstra 的時候,只需要不斷比較有無使用 special road 的 cost。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| int minimumCost(vector<int>& start, vector<int>& target, vector<vector<int>>& specialRoads) {
int n = specialRoads.size();
vector<int> shortest(n, INT_MAX); // 記錄從 start 到第 i 個 specialRoad 終點的最短距離
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
for (int i = 0; i < n; i++){
int x1 = specialRoads[i][0];
int y1 = specialRoads[i][1];
int x2 = specialRoads[i][2];
int y2 = specialRoads[i][3];
int cost = specialRoads[i][4];
int with_road = abs(start[0] - x1) + abs(start[1] - y1) + cost; // 有使用 specialRoad
int without_road = abs(start[0] - x2) + abs(start[1] - y2); // 沒有使用 specialRoad
pq.push({min(with_road, without_road), i});
}
while (not pq.empty()){
auto [distance, index] = pq.top();
pq.pop();
if (shortest[index] != INT_MAX){
continue;
}
shortest[index] = distance;
for (int i = 0; i < n; i++){
if (shortest[i] != INT_MAX){
continue;
}
int x1 = specialRoads[i][0];
int y1 = specialRoads[i][1];
int x2 = specialRoads[i][2];
int y2 = specialRoads[i][3];
int cost = specialRoads[i][4];
int with_road = abs(specialRoads[index][2] - x1) + abs(specialRoads[index][3] - y1) + cost;
int without_road = abs(specialRoads[index][2] - x2) + abs(specialRoads[index][3] - y2);
pq.push({distance + min(with_road, without_road), i});
}
}
int ans = abs(start[0] - target[0]) + abs(start[1] - target[1]);
// 最後檢查從第 i 個 specialRoad 的終點到 target 的距離
// 如果更短的話就更新最小值
for (int i = 0; i < n; i++){
ans = min(ans, shortest[i] + abs(specialRoads[i][2] - target[0]) + abs(specialRoads[i][3] - target[1]));
}
return ans;
}
|
time complexity: $O(n^2 \log n)$
space complextiy: $O(n^2)$
where n = specialRoads.size()
解完之後看了一下 leetcode discussion,發現大家的解法似乎簡單一些,但是目前還沒看懂,理解之後再更新。