Description Link to heading
1976. Number of Ways to Arrive at Destination (Medium)
You are in a city that consists of n
intersections numbered from 0
to n - 1
with
bi-directional roads between some intersections. The inputs are generated such that you can
reach any intersection from any other intersection and that there is at most one road between any
two intersections.
You are given an integer n
and a 2D integer array roads
where roads[i] = [uᵢ, vᵢ, timeᵢ]
means
that there is a road between intersections uᵢ
and vᵢ
that takes timeᵢ
minutes to travel. You
want to know in how many ways you can travel from intersection 0
to intersection n - 1
in the
shortest amount of time.
Return the number of ways you can arrive at your destination in the shortest amount of time.
Since the answer may be large, return it modulo 10⁹ + 7
.
Example 1:
Input: n = 7, roads =
[[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
Output: 4
Explanation: The shortest amount of time it takes to go from intersection 0 to intersection 6 is 7
minutes.
The four ways to get there in 7 minutes are:
- 0 ➝ 6
- 0 ➝ 4 ➝ 6
- 0 ➝ 1 ➝ 2 ➝ 5 ➝ 6
- 0 ➝ 1 ➝ 3 ➝ 5 ➝ 6
Example 2:
Input: n = 2, roads = [[1,0,10]]
Output: 1
Explanation: There is only one way to go from intersection 0 to intersection 1, and it takes 10
minutes.
Constraints:
1 <= n <= 200
n - 1 <= roads.length <= n * (n - 1) / 2
roads[i].length == 3
0 <= uᵢ, vᵢ <= n - 1
1 <= timeᵢ <= 10⁹
uᵢ != vᵢ
- There is at most one road connecting any two intersections.
- You can reach any intersection from any other intersection.
Solution Link to heading
First, we can use the Dijkstra algorithm to find the minimum distance from $n-1$ to each point, and then use memorized search to find the answer.
If the distance of any two neighboring points is the minimum, then the distance of the path is the minimum.
Code Link to heading
class Solution {
public:
int mod = 1000000007;
void Dijkstra(vector<vector<vector<int>>> &graph, vector<long> &dis, int start_idx, vector<int> &is_min) {
auto cmp = [&](pair<int, long> &p1, pair<int, long> &p2) {
return p1.second > p2.second;
};
priority_queue<pair<int, long>, vector<pair<int, long>>, decltype(cmp)> pq(cmp);
pq.push({start_idx, 0});
while (!pq.empty()) {
auto [idx, len] = pq.top();
pq.pop();
if (is_min[idx] == 1) {
continue;
}
dis[idx] = len; // update the minimum distance
is_min[idx] = 1; // the minimum distance is found
for (auto &vec : graph[idx]) {
if (is_min[vec[0]] == 0) {
pq.push({vec[0], len + vec[1]});
}
}
}
}
int dfs(vector<int> &used, vector<vector<vector<int>>> &graph, int idx, vector<long> &disn, vector<int> &cach) {
if (idx == 0) {
return 1;
}
if (cach[idx] != -1) {
return cach[idx];
}
int res = 0;
for (auto &vec : graph[idx]) {
// if (dis0[vec[0]] + disn[vec[0]] == disn[0] && dis0[idx] > dis0[vec[0]] && vec[1] + disn[idx] == disn[vec[0]]) {
if (vec[1] + disn[idx] == disn[vec[0]]) {
res = (res + dfs(used, graph, vec[0], disn, cach)) % mod;
}
}
cach[idx] = res;
return cach[idx];
}
int countPaths(int n, vector<vector<int>> &roads) {
vector<vector<vector<int>>> graph(n);
for (auto &road : roads) {
graph[road[0]].push_back({road[1], road[2]});
graph[road[1]].push_back({road[0], road[2]});
}
vector<long> disn(n);
vector<int> is_minn(n);
// Dijkstra(graph, dis0, 0, is_min0);
Dijkstra(graph, disn, n - 1, is_minn);
vector<int> used(n);
vector<int> cach(n, -1);
return dfs(used, graph, n - 1, disn, cach);
}
};