|
| 1 | +// Time: O((|E| + |V|) * log|V|) = O(|E| * log|V|) by using binary heap, |
| 2 | +// if we can further to use Fibonacci heap, it would be O(|E| + |V| * log|V|) |
| 3 | +// Space: O(|E| + |V|) = O(|E|) |
| 4 | + |
| 5 | +class Solution { |
| 6 | +public: |
| 7 | + int minimumCost(int n, vector<vector<int>>& highways, int discounts) { |
| 8 | + using P = pair<int, int>; |
| 9 | + unordered_map<int, vector<P>> adj; |
| 10 | + for (const auto& highway : highways) { |
| 11 | + int u, v, w; |
| 12 | + tie(u, v, w) = make_tuple(highway[0], highway[1], highway[2]); |
| 13 | + adj[u].emplace_back(v, w); |
| 14 | + adj[v].emplace_back(u, w); |
| 15 | + } |
| 16 | + |
| 17 | + unordered_map<int, unordered_map<int, int>> best; |
| 18 | + best[0][discounts] = 0; |
| 19 | + using T = tuple<int, int, int>; |
| 20 | + priority_queue<T, vector<T>, greater<T>> min_heap; |
| 21 | + min_heap.emplace(0, 0, discounts); |
| 22 | + while (!empty(min_heap)) { |
| 23 | + auto [total, u, k] = min_heap.top(); min_heap.pop(); |
| 24 | + if ((best.count(u) && best[u].count(k) && best[u][k] < total)) { |
| 25 | + continue; |
| 26 | + } |
| 27 | + if (u == n - 1) { |
| 28 | + return total; |
| 29 | + } |
| 30 | + for (const auto& [v, w] : adj[u]) { |
| 31 | + if (!best.count(v) || |
| 32 | + !best[v].count(k) || |
| 33 | + total + w < best[v][k]) { |
| 34 | + best[v][k] = total + w; |
| 35 | + min_heap.emplace(total + w, v, k); |
| 36 | + } |
| 37 | + if (k > 0 && |
| 38 | + (!best.count(v) || |
| 39 | + !best[v].count(k - 1) || |
| 40 | + total + w / 2 < best[v][k - 1])) { |
| 41 | + best[v][k - 1] = total + w / 2; |
| 42 | + min_heap.emplace(total + w / 2, v, k - 1); |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + return -1; |
| 47 | + } |
| 48 | +}; |
0 commit comments