有 n 个网络节点,标记为 1 到 n。
给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。
现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。
示例 1:
输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出:2
示例 2:
输入:times = [[1,2,1]], n = 2, k = 1
输出:1
示例 3:
输入:times = [[1,2,1]], n = 2, k = 2
输出:-1
提示:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
所有 (ui, vi) 对都 互不相同(即,不含重复边)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/network-delay-time
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:优先队列实现迪杰斯特拉算法;
1、利用Map建立每一个节点与以它为出发点的所有边的集合;
2、建立优先队列存储所有边的出发点,目的点,以及从k点出发到目的点的路径长度;
3、找寻从k点出发可以到达的边,并将其放入优先队列进行初始化;
4、当优先队列非空时对其进行遍历,找出从k点到达某个目的点最短的那条路径;
5、将该目的点所能到达的点记录进优先队列,注意此时需要将weight更新为k点出发到目的点的路径长度;
6、将步骤4,5循环直到队列空;
7、判断是否有某个点无法到达,若是返回-1,若否,返回dis中的最大路径长度;
注意: 优先队列的边的权重更新为k点出发到目的点的路径长度,而非源点到目标点的路径长度的目的是为了避免出现【1,2,3】,【1,3,4】,【2,3,2】这种情况的出现;
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
//起点与其所在的index
Map<Integer, List<Integer>> collect=new HashMap<>();
for(int i=0;i<times.length;i++){
List<Integer> list = collect.getOrDefault(times[i][0], new ArrayList<>());
list.add(i);
collect.put(times[i][0],list);
}
//终点与权值
PriorityQueue<int[]> queue=new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[2]-o2[2];
}
});
//初始化优先队列
if(collect.containsKey(k)){
List<Integer> list = collect.get(k);
list.forEach(index->{
queue.offer(times[index]);
});
}
int dis[]=new int[n+1];
//实际上可以不使用visit数组
boolean visit[]=new boolean[n+1];
Arrays.fill(dis,-1);
dis[k]=0;
visit[k]=true;
while(!queue.isEmpty()){
int head[]=queue.poll();
int source=head[0];
int target=head[1];
int weight=head[2];
if(!visit[target]){
dis[target]=weight;
collect.getOrDefault(target,new ArrayList<>()).forEach(index->{
times[index][2]=dis[target]+times[index][2];
queue.offer(times[index]);
});
visit[target]=true;
}
}
int res=-1;
for (int i = 1; i < dis.length; i++) {
if(dis[i]==-1) return -1;
else res=Math.max(res,dis[i]);
}
return res;
}
}