|
| 1 | +// Time: O(n * m * logn(n * m)) |
| 2 | +// Space: O(n * m) |
| 3 | + |
| 4 | +// dijkstra's algorithm |
| 5 | +class Solution { |
| 6 | +public: |
| 7 | + int minTimeToReach(vector<vector<int>>& moveTime) { |
| 8 | + static const int INF = numeric_limits<int>::max(); |
| 9 | + static const vector<pair<int, int>> DIRECTIONS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; |
| 10 | + |
| 11 | + const auto& dijkstra = [&](const pair<int, int>& start, const pair<int, int>& target) { |
| 12 | + vector<vector<int>> dist(size(moveTime), vector<int>(size(moveTime[0]), INF)); |
| 13 | + dist[start.first][start.second] = 0; |
| 14 | + priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> min_heap; |
| 15 | + min_heap.emplace(dist[start.first][start.second], start.first, start.second); |
| 16 | + while (!empty(min_heap)) { |
| 17 | + const auto [curr, i, j] = min_heap.top(); min_heap.pop(); |
| 18 | + if (curr != dist[i][j]) { |
| 19 | + continue; |
| 20 | + } |
| 21 | + if (pair(i, j) == target) { |
| 22 | + break; |
| 23 | + } |
| 24 | + for (const auto& [di, dj] : DIRECTIONS) { |
| 25 | + const int ni = i + di, nj = j + dj; |
| 26 | + const int c = 1; |
| 27 | + if (!(0 <= ni && ni < size(moveTime) && 0 <= nj && nj < size(moveTime[0]) && dist[ni][nj] > max(moveTime[ni][nj], curr) + c)) { |
| 28 | + continue; |
| 29 | + } |
| 30 | + dist[ni][nj] = max(moveTime[ni][nj], curr) + c; |
| 31 | + min_heap.emplace(dist[ni][nj], ni, nj); |
| 32 | + } |
| 33 | + } |
| 34 | + return dist[target.first][target.second]; |
| 35 | + }; |
| 36 | + |
| 37 | + return dijkstra({0, 0}, {size(moveTime) - 1, size(moveTime[0]) - 1}); |
| 38 | + } |
| 39 | +}; |
0 commit comments