LeetCode743网络延迟时间-----迪杰斯特拉算法
题目表述
有 n 个网络节点,标记为 1 到 n。
给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。
现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。
Disjkstra算法
- 使用邻接矩阵graph存储图的信息,graph[i][j]代表i到j的边的权重。
- 将将邻接矩阵graph中值初始化为INF,并根据给定的矩阵信息更新邻接矩阵中的值。
- 创建一个distance数组,代表源节点到各节点之间的距离,并初始化为INF,其中源节点到其本身初始化为0;
- 创建一个访问数组visited,代表已经访问过的节点。
- 每次从distance数组中选择距离最短的节点进行更新,并将该节点标记已访问。
class Solution {
static final int INF = 0x3f3f3f3f;
public static int networkDelayTime(int[][] times, int n, int k) {
int res = -1;
int[][] graph = new int[n][n]; // 新建邻接矩阵
for(int[] tmp : graph){
Arrays.fill(tmp, INF); // 将邻接矩阵中的值初始化为最大值
}
for(int[] tmp : times){
graph[tmp[0] - 1][tmp[1] - 1] = tmp[2]; // 根据已有矩阵信息更新邻接矩阵
}
int[] distance = new int[n]; // 新建距离数组
Arrays.fill(distance, INF); // 将距离数组初始化为最大值
distance[k-1] = 0; //源节点到其本身的距离为0
boolean[] visited = new boolean[n]; // 新建访问数组
dijkstra(graph, visited,distance, n); // 迪杰斯特拉算法迭代计算源节点到各节点最短路径
for (int tmp : distance){
res = Math.max(res,tmp);
}
return res == INF? -1 : res;
}
public static void dijkstra(int[][] graph, boolean[] visited, int[] distance,int n){
for(int i = 0; i < n; i++){ // 迭代,每次寻找最短路径进行更新
int minIndex = 0;
int minDis = INF; // minDis代表最短距离, minIndex代表最短距离所对应的下标
for(int j = 0; j < n; j++){// 在distance数组中寻找最短路径
if(!visited[j] && distance[j] < minDis){
minDis = distance[j];
minIndex = j;
}
}
visited[minIndex] = true;
for(int k = 0; k < n;k++){ // 更新路径
distance[k] = Math.min(distance[k], distance[minIndex] + graph[minIndex][k]);
}
}
}
}
代码优化(小顶堆)
将源节点到各节点距离和节点编号存入小顶堆中,按距离排序,这样每次取出的都是距离最短的节点。
public static int networkDelayTime(int[][] times, int n, int k) {
List<int[]>[] g = new List[n];
for(int i = 0; i < n;i++){
g[i] = new ArrayList<>();
}
for(int[] t : times){
g[t[0]-1].add(new int[]{t[1]-1, t[2]});
}
int[] dist = new int[n];
Arrays.fill(dist,INF);
dist[k - 1] = 0;
PriorityQueue<int[]> que = new PriorityQueue<>((a,b) ->{
return a[0] != b[0]? a[0] - b[0] : a[1] - b[1];
});
que.offer(new int[]{0,k-1});
while(!que.isEmpty()){
int[] p = que.poll();
int time = p[0], x = p[1];
if(time > dist[x]){
continue;
}
for(int[] e: g[x]){
int y = e[0];
int d = e[1] + time;
if(d < dist[y]){
dist[y] = d;
que.offer(new int[]{d, y});
}
}
}
int ans = Arrays.stream(dist).max().getAsInt();
return ans == INF? -1 : ans;
}