54
54
55
55
### 方法一:朴素 Dijkstra 算法
56
56
57
- 在求最短路的过程中顺便记录到达某个点最短路径的方案数。松弛优化时,如果发现有更优的路径,则方案数也赋值最优路径的前驱的方案数。如果发现与最优的路径长度相同,则累加当前前驱的方案数。
57
+ 我们定义以下几个数组,其中:
58
58
59
- 由于图有可能非常稠密,所以采用朴素的 Dijkstra 算法。
59
+ - ` g ` 表示图的邻接矩阵,` g[i][j] ` 表示点 ` i ` 到点 ` j ` 的最短路径长度,初始时全部为 $\infty$,而 ` g[0][0] ` 为 $0$;然后我们遍历 ` roads ` ,将 ` g[u][v] ` 和 ` g[v][u] ` 更新为 ` t ` ;
60
+ - ` dist[i] ` 表示从起点到点 ` i ` 的最短路径长度,初始时全部为 $\infty$,而 ` dist[0] ` 为 $0$;
61
+ - ` f[i] ` 表示从起点到点 ` i ` 的最短路径的条数,初始时全部为 $0$,而 ` f[0] ` 为 $1$;
62
+ - ` vis[i] ` 表示点 ` i ` 是否已经被访问过,初始时全部为 ` False ` 。
60
63
61
- 时间复杂度 $O(n^2)$ 。
64
+ 然后,我们使用朴素 Dijkstra 算法求出从起点到终点的最短路径长度,过程中同时记录下每个点的最短路径的条数 。
62
65
63
- > 注意:最短路的长度可能会超过 32 位整数的范围。
66
+ 最后,我们返回 ` f[n - 1] ` 即可。由于答案可能很大,我们需要对 $10^9 + 7$ 取模。
67
+
68
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为点的个数。
64
69
65
70
<!-- tabs:start -->
66
71
67
72
``` python
68
73
class Solution :
69
74
def countPaths (self , n : int , roads : List[List[int ]]) -> int :
70
- INF = inf
71
- MOD = 10 ** 9 + 7
72
- g = [[INF ] * n for _ in range (n)]
75
+ g = [[inf] * n for _ in range (n)]
73
76
for u, v, t in roads:
74
- g[u][v] = t
75
- g[v][u] = t
77
+ g[u][v] = g[v][u] = t
76
78
g[0 ][0 ] = 0
77
- dist = [INF ] * n
78
- w = [0 ] * n
79
+ dist = [inf] * n
79
80
dist[0 ] = 0
80
- w[0 ] = 1
81
+ f = [0 ] * n
82
+ f[0 ] = 1
81
83
vis = [False ] * n
82
84
for _ in range (n):
83
85
t = - 1
84
- for i in range (n):
85
- if not vis[i ] and (t == - 1 or dist[i ] < dist[t]):
86
- t = i
86
+ for j in range (n):
87
+ if not vis[j ] and (t == - 1 or dist[j ] < dist[t]):
88
+ t = j
87
89
vis[t] = True
88
- for i in range (n):
89
- if i == t:
90
+ for j in range (n):
91
+ if j == t:
90
92
continue
91
- ne = dist[t] + g[t][i]
92
- if dist[i] > ne:
93
- dist[i] = ne
94
- w[i] = w[t]
95
- elif dist[i] == ne:
96
- w[i] += w[t]
97
- return w[- 1 ] % MOD
93
+ ne = dist[t] + g[t][j]
94
+ if dist[j] > ne:
95
+ dist[j] = ne
96
+ f[j] = f[t]
97
+ elif dist[j] == ne:
98
+ f[j] += f[t]
99
+ mod = 10 ** 9 + 7
100
+ return f[- 1 ] % mod
98
101
```
99
102
100
103
``` java
101
104
class Solution {
102
- private static final long INF = Long . MAX_VALUE / 2 ;
103
- private static final int MOD = (int ) 1e9 + 7 ;
104
-
105
105
public int countPaths (int n , int [][] roads ) {
106
+ final long inf = Long . MAX_VALUE / 2 ;
107
+ final int mod = (int ) 1e9 + 7 ;
106
108
long [][] g = new long [n][n];
107
- long [] dist = new long [n];
108
- long [] w = new long [n];
109
- boolean [] vis = new boolean [n];
110
- for (int i = 0 ; i < n; ++ i) {
111
- Arrays . fill(g[i], INF );
112
- Arrays . fill(dist, INF );
109
+ for (var e : g) {
110
+ Arrays . fill(e, inf);
113
111
}
114
- for (int [] r : roads) {
112
+ for (var r : roads) {
115
113
int u = r[0 ], v = r[1 ], t = r[2 ];
116
114
g[u][v] = t;
117
115
g[v][u] = t;
118
116
}
119
117
g[0 ][0 ] = 0 ;
118
+ long [] dist = new long [n];
119
+ Arrays . fill(dist, inf);
120
120
dist[0 ] = 0 ;
121
- w[0 ] = 1 ;
121
+ long [] f = new long [n];
122
+ f[0 ] = 1 ;
123
+ boolean [] vis = new boolean [n];
122
124
for (int i = 0 ; i < n; ++ i) {
123
125
int t = - 1 ;
124
126
for (int j = 0 ; j < n; ++ j) {
@@ -134,85 +136,102 @@ class Solution {
134
136
long ne = dist[t] + g[t][j];
135
137
if (dist[j] > ne) {
136
138
dist[j] = ne;
137
- w [j] = w [t];
139
+ f [j] = f [t];
138
140
} else if (dist[j] == ne) {
139
- w [j] = (w [j] + w [t]) % MOD ;
141
+ f [j] = (f [j] + f [t]) % mod ;
140
142
}
141
143
}
142
144
}
143
- return (int ) w [n - 1 ];
145
+ return (int ) f [n - 1 ];
144
146
}
145
147
}
146
148
```
147
149
148
150
``` cpp
149
- typedef long long ll;
150
-
151
151
class Solution {
152
152
public:
153
- const ll INF = LLONG_MAX / 2;
154
- const int MOD = 1e9 + 7;
155
-
156
153
int countPaths(int n, vector<vector<int >>& roads) {
157
- vector<vector<ll>> g(n, vector<ll>(n, INF));
158
- vector<ll> dist(n, INF);
159
- vector<ll> w(n);
160
- vector<bool> vis(n);
154
+ const long long inf = LLONG_MAX / 2;
155
+ const int mod = 1e9 + 7;
156
+
157
+ vector<vector<long long>> g(n, vector<long long>(n, inf));
158
+ for (auto& e : g) {
159
+ fill(e.begin(), e.end(), inf);
160
+ }
161
+
161
162
for (auto & r : roads) {
162
163
int u = r[0], v = r[1], t = r[2];
163
164
g[u][v] = t;
164
165
g[v][u] = t;
165
166
}
167
+
166
168
g[0][0] = 0;
169
+
170
+ vector<long long> dist(n, inf);
171
+ fill (dist.begin(), dist.end(), inf);
167
172
dist[ 0] = 0;
168
- w[0 ] = 1 ;
173
+
174
+ vector<long long> f(n);
175
+ f[0] = 1;
176
+
177
+ vector<bool> vis(n);
169
178
for (int i = 0; i < n; ++i) {
170
179
int t = -1;
171
180
for (int j = 0; j < n; ++j) {
172
- if (!vis[j] && (t == -1 || dist[t] > dist[j])) t = j;
181
+ if (!vis[j] && (t == -1 || dist[j] < dist[t])) {
182
+ t = j;
183
+ }
173
184
}
174
185
vis[t] = true;
175
186
for (int j = 0; j < n; ++j) {
176
- if (t == j) continue;
177
- ll ne = dist[t] + g[t][j];
187
+ if (j == t) {
188
+ continue;
189
+ }
190
+ long long ne = dist[t] + g[t][j];
178
191
if (dist[j] > ne) {
179
192
dist[j] = ne;
180
- w[j] = w[t];
181
- } else if (dist[j] == ne)
182
- w[j] = (w[j] + w[t]) % MOD;
193
+ f[j] = f[t];
194
+ } else if (dist[j] == ne) {
195
+ f[j] = (f[j] + f[t]) % mod;
196
+ }
183
197
}
184
198
}
185
- return w [n - 1];
199
+ return (int) f [n - 1];
186
200
}
187
201
};
188
202
```
189
203
190
204
``` go
191
205
func countPaths (n int , roads [][]int ) int {
192
206
const inf = math.MaxInt64 / 2
193
- const mod = int (1e9 ) + 7
207
+ const mod = int (1e9 + 7 )
208
+
194
209
g := make ([][]int , n)
195
210
dist := make ([]int , n)
196
- w := make ([]int , n)
197
- vis := make ([]bool , n)
198
211
for i := range g {
199
212
g[i] = make ([]int , n)
200
- dist[i] = inf
201
213
for j := range g[i] {
202
214
g[i][j] = inf
215
+ dist[i] = inf
203
216
}
204
217
}
218
+
205
219
for _ , r := range roads {
206
220
u , v , t := r[0 ], r[1 ], r[2 ]
207
- g[u][v], g[v][u] = t, t
221
+ g[u][v] = t
222
+ g[v][u] = t
208
223
}
224
+
225
+ f := make ([]int , n)
226
+ vis := make ([]bool , n)
227
+ f[0 ] = 1
209
228
g[0 ][0 ] = 0
210
229
dist[0 ] = 0
211
- w[ 0 ] = 1
230
+
212
231
for i := 0 ; i < n; i++ {
213
232
t := -1
214
233
for j := 0 ; j < n; j++ {
215
- if !vis[j] && (t == -1 || dist[t] > dist[j ]) {
234
+ if !vis[j] && (t == -1 || dist[j] < dist[t ]) {
216
235
t = j
217
236
}
218
237
}
@@ -224,13 +243,55 @@ func countPaths(n int, roads [][]int) int {
224
243
ne := dist[t] + g[t][j]
225
244
if dist[j] > ne {
226
245
dist[j] = ne
227
- w [j] = w [t]
246
+ f [j] = f [t]
228
247
} else if dist[j] == ne {
229
- w [j] = (w [j] + w [t]) % mod
248
+ f [j] = (f [j] + f [t]) % mod
230
249
}
231
250
}
232
251
}
233
- return w[n-1 ]
252
+ return f[n-1 ]
253
+ }
254
+ ```
255
+
256
+ ``` ts
257
+ function countPaths(n : number , roads : number [][]): number {
258
+ const mod: number = 1e9 + 7 ;
259
+ const g: number [][] = Array .from ({ length: n }, () => Array (n ).fill (Infinity ));
260
+ for (const [u, v, t] of roads ) {
261
+ g [u ][v ] = t ;
262
+ g [v ][u ] = t ;
263
+ }
264
+ g [0 ][0 ] = 0 ;
265
+
266
+ const dist: number [] = Array (n ).fill (Infinity );
267
+ dist [0 ] = 0 ;
268
+
269
+ const f: number [] = Array (n ).fill (0 );
270
+ f [0 ] = 1 ;
271
+
272
+ const vis: boolean [] = Array (n ).fill (false );
273
+ for (let i = 0 ; i < n ; ++ i ) {
274
+ let t: number = - 1 ;
275
+ for (let j = 0 ; j < n ; ++ j ) {
276
+ if (! vis [j ] && (t === - 1 || dist [j ] < dist [t ])) {
277
+ t = j ;
278
+ }
279
+ }
280
+ vis [t ] = true ;
281
+ for (let j = 0 ; j < n ; ++ j ) {
282
+ if (j === t ) {
283
+ continue ;
284
+ }
285
+ const ne: number = dist [t ] + g [t ][j ];
286
+ if (dist [j ] > ne ) {
287
+ dist [j ] = ne ;
288
+ f [j ] = f [t ];
289
+ } else if (dist [j ] === ne ) {
290
+ f [j ] = (f [j ] + f [t ]) % mod ;
291
+ }
292
+ }
293
+ }
294
+ return f [n - 1 ];
234
295
}
235
296
```
236
297
0 commit comments