文章目录
- [1976. 到达目的地的方案数](https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/)
- 思路:
- 代码:
1976. 到达目的地的方案数
思路:
利用 Dijkstra 算法计算最短路径,并同时记录最短路径的数量,以解决从起点到终点的最短路径数量的问题
- 使用邻接矩阵 g 存储节点之间的距离,其中 g[x][y] 表示节点 x 到节点 y 的距离,因为是无向图,所以 g[y][x] 也表示相同的距离。
- 初始化距离数组 dis 和路径数量数组 f。dis 存储从起点到每个节点的最短距离,f 存储从起点到每个节点的最短路径数量。
- 根据 Dijkstra 算法的思想,不断更新未确定最短路径长度的节点,直到找到从起点到终点的最短路径。
- 在更新节点的过程中,根据新的距离和之前求得的最短距离的比较,更新最短路径长度和路径数量。如果发现新的最短路径或者相同长度的最短路径,就更新路径数量。
- 当找到从起点到终点的最短路径时,返回终点的最短路径数量。
代码:
//1976. 到达目的地的方案数--Dijkstra
public int countPaths(int n, int[][] roads) {
long[][] g = new long[n][n]; // 邻接矩阵,用于存储节点之间的距离
for (long[] row : g) {
Arrays.fill(row, Long.MAX_VALUE / 2); // 初始化邻接矩阵,将所有距离设置为一个较大的值以防止溢出
}
for (int[] r : roads) {
int x = r[0];
int y = r[1];
int d = r[2];
g[x][y] = d; // 将节点x和节点y之间的距离设置为d
g[y][x] = d; // 因为是无向图,所以节点x和节点y之间的距离相同
}
long[] dis = new long[n]; // 存储从起点到每个节点的最短距离
Arrays.fill(dis, 1, n, Long.MAX_VALUE / 2); // 初始化dis数组,将除起点外的距离设置为一个较大的值以防止溢出
int[] f = new int[n]; // 存储从起点到每个节点的最短路径数量
f[0] = 1; // 起点到自身的最短路径数量为1
boolean[] done = new boolean[n]; // 标记节点是否已经确定最短路径长度
while (true) {
int x = -1;
for (int i = 0; i < n; i++) {
if (!done[i] && (x < 0 || dis[i] < dis[x])) {
x = i; // 找到未确定最短路径长度的节点中距离最小的节点
}
}
if (x == n - 1) {
// 如果最小距离的节点是终点,那么已经找到了从起点到终点的最短路径
// 不可能找到比 dis[n-1] 更短,或者一样短的最短路了(注意本题边权都是正数)
return f[n - 1]; // 返回起点到终点的最短路径数量
}
done[x] = true; // 最短路径长度已确定(无法变得更小)
for (int y = 0; y < n; y++) { // 尝试更新节点x的邻居的最短路径
long newDis = dis[x] + g[x][y]; // 计算从起点经过节点x到达节点y的距离
if (newDis < dis[y]) {
// 如果新的距离比之前求得的最短距离更小,说明发现了一条更新的最短路径
dis[y] = newDis; // 更新节点y的最短路径长度
f[y] = f[x]; // 节点y的最短路径数量等于节点x的最短路径数量
} else if (newDis == dis[y]) {
// 如果新的距离和之前求得的最短距离一样长,说明找到了一条相同长度的最短路径
f[y] = (f[y] + f[x]) % 1_000_000_007; // 更新节点y的最短路径数量,累加节点x的最短路径数量
}
}
}
}
点击移步博客主页,欢迎光临~