forked from haoel/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NumberOfRestrictedPathsFromFirstToLastNode.cpp
129 lines (112 loc) · 4.43 KB
/
NumberOfRestrictedPathsFromFirstToLastNode.cpp
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Source : https://leetcode.com/problems/number-of-restricted-paths-from-first-to-last-node/
// Author : Hao Chen
// Date : 2021-03-07
/*****************************************************************************************************
*
* There is an undirected weighted connected graph. You are given a positive integer n which denotes
* that the graph has n nodes labeled from 1 to n, and an array edges where each edges[i] = [ui, vi,
* weighti] denotes that there is an edge between nodes ui and vi with weight equal to weighti.
*
* A path from node start to node end is a sequence of nodes [z0, z1, z2, ..., zk] such that z0 =
* start and zk = end and there is an edge between zi and zi+1 where 0 <= i <= k-1.
*
* The distance of a path is the sum of the weights on the edges of the path. Let
* distanceToLastNode(x) denote the shortest distance of a path between node n and node x. A
* restricted path is a path that also satisfies that distanceToLastNode(zi) >
* distanceToLastNode(zi+1) where 0 <= i <= k-1.
*
* Return the number of restricted paths from node 1 to node n. Since that number may be too large,
* return it modulo 109 + 7.
*
* Example 1:
*
* Input: n = 5, edges = [[1,2,3],[1,3,3],[2,3,1],[1,4,2],[5,2,2],[3,5,1],[5,4,10]]
* Output: 3
* Explanation: Each circle contains the node number in black and its distanceToLastNode value in
* blue. The three restricted paths are:
* 1) 1 --> 2 --> 5
* 2) 1 --> 2 --> 3 --> 5
* 3) 1 --> 3 --> 5
*
* Example 2:
*
* Input: n = 7, edges = [[1,3,1],[4,1,2],[7,3,4],[2,5,3],[5,6,1],[6,7,2],[7,5,3],[2,6,4]]
* Output: 1
* Explanation: Each circle contains the node number in black and its distanceToLastNode value in
* blue. The only restricted path is 1 --> 3 --> 7.
*
* Constraints:
*
* 1 <= n <= 2 * 104
* n - 1 <= edges.length <= 4 * 104
* edges[i].length == 3
* 1 <= ui, vi <= n
* ui != vi
* 1 <= weighti <= 105
* There is at most one edge between any two nodes.
* There is at least one path between any two nodes.
******************************************************************************************************/
class Solution {
void printVector(vector<int>& v) {
cout << "[";
for (int i = 0; i< v.size() -1 ; i ++) {
cout << v[i] << ", ";
}
cout << v[v.size()-1] << "]" << endl;
}
public:
int countRestrictedPaths(int n, vector<vector<int>>& edges) {
// re-orginanize the graph map
vector<unordered_map<int, int>> graph(n);
for(auto e : edges) {
int x = e[0]-1;
int y = e[1]-1;
int d = e[2];
graph[x][y] = graph[y][x] = d;
}
//Dijkstra Algorithm
vector<int> distance(n, INT_MAX);
distance[n-1] = 0;
auto cmp = [&](const int& lhs, const int& rhs) {return distance[lhs] > distance[rhs]; };
priority_queue<int, vector<int>, decltype(cmp)> nodes(cmp);
nodes.push(n-1);
while( !nodes.empty() ) {
int x = nodes.top(); nodes.pop();
for(const auto & [ y, d ] : graph[x]) {
if ( distance[y] > d + distance[x] ) {
distance[y] = d + distance[x];
// if the node's distance is updated,
// it's neighbor must be recaluated
nodes.push(y);
}
}
}
//printVector(distance);
//Dynamic Programming for restric paths
vector<bool> visited(n, false);
vector<long> restriced_path(n, 0);
nodes.push(n-1);
restriced_path[n-1] = 1;
visited[n-1] = true;
while( !nodes.empty() ) {
int x = nodes.top(); nodes.pop();
//cout << x+1 << ":";
for(const auto & [ y, d ] : graph[x]) {
if ( distance[y] > distance[x]) {
restriced_path[y] += restriced_path[x];
restriced_path[y] %= 1000000007;
}
if (!visited[y]) {
//cout << y+1 << ",";
nodes.push(y);
visited[y] = true;
}
}
//cout<<endl;
//printVector(restriced_path);
}
//cout << "-------" <<endl;
//printVector(restriced_path);
return restriced_path[0];
}
};