Leetcode743. 网络延迟时间

有 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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值