Dijkstra 算法 : 若有 包含负权重的边的 环, 失效
class Solution:
def countPaths(self, n: int, roads: List[List[int]]) -> int:
# 邻接表
# 优先队列: 路径时长, 点的编号 0 到 node 的路径最短时长 不断刷新
e = [[] for _ in range(n)] # 邻接表
for u, v, t in roads:
e[u].append((v, t))
e[v].append((u, t))
times = [0] + [inf] * (n - 1) # 0 到 结点 i 的路径最短时长为 times[i]
ways = [1] + [0] * (n - 1) # 获得 0 到 结点 i 的最短时长路径 的方案数 为 ways[i]
mod = 10**9 + 7
q = [[0, 0]] # 路径时长 结点 根据路径时长 维护 小根树
while q:
cur, u = heappop(q) # 结点 u 即其 最短时长
if cur > times[u]:
continue
for v, t in e[u]:
if cur + t < times[v]:
times[v] = cur + t
ways[v] = ways[u]
heappush(q, [cur + t, v])
elif cur + t == times[v]:
ways[v] = (ways[u] + ways[v]) % mod
return ways[-1]
class Solution {
public:
int countPaths(int n, vector<vector<int>>& roads) {
const long long mod = 1e9 + 7;
vector<vector<pair<int, int>>> e(n);
for (auto r : roads){
int u = r[0], v = r[1], t = r[2];
e[u].emplace_back(v, t);
e[v].emplace_back(u, t);
}
vector<long long> dis(n, LLONG_MAX);
vector<long long> ways(n); // 0 到 结点 i 获得 最短路径 dis[i] 的方法数
priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q; // 优先弹出 最小值
q.emplace(0, 0); // 最短路径时长 结点
dis[0] = 0;
ways[0] = 1;
while (!q.empty()){
auto [t, u] = q.top(); q.pop();
if (t > dis[u]){
continue;
}
for (auto [v, w] : e[u]){
if (t + w < dis[v]){
dis[v] = t + w;
ways[v] = ways[u];
q.emplace(t + w, v);
}else if (t + w == dis[v]){
ways[v] = (ways[u] + ways[v]) % mod;
}
}
}
return ways[n - 1];
}
};