743. 网络延迟时间

题目

有 n 个网络节点,标记为 1 到 n。

给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。

现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/network-delay-time
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。在这里插入图片描述

代码

class Solution {
    public int networkDelayTime(int[][] times, int n, int k) {
        // 节点编号是从 1 开始的,所以要一个大小为 n + 1 的邻接表
        List<int[]>[] gragh=new LinkedList[n+1];
        for (int i = 1; i <=n ; i++) {
            gragh[i]=new LinkedList<>();//实例化
        }
        //构造图
        for (int[] edge: times
             ) {
            int from=edge[0];
            int to  =edge[1];
            int weight=edge[2];
            // from -> List<(to, weight)>
            // 邻接表存储图结构,同时存储权重信息
            gragh[from].add(new int[]{to,weight});
        }
        // 启动 dijkstra 算法计算以节点 k 为起点到其他节点的最短路径
        int[] distTo=dijkstra(k,gragh);

        // 找到最长的那一条最短路径
        int ans=0;
        for (int i = 1; i <distTo.length ; i++) {
            if (distTo[i]==Integer.MAX_VALUE){
                return -1;//因为有些结点无法达到
            }
            ans =Math.max(ans,distTo[i]);
        }

        return ans;

    }

    // 输入一个起点 start,计算从 start 到其他节点的最短距离
    int[] dijkstra(int start, List<int[]>[] graph){
        // 定义:distTo[i] 的值就是起点 start 到达节点 i 的最短路径权重
        int[] distTo =new int[graph.length];
        Arrays.fill(distTo,Integer.MAX_VALUE);//赋值无穷大
        // base case,start 到 start 的最短距离就是 0
        distTo[start]=0;

        // 优先级队列,distFromStart 较小的排在前面
        PriorityQueue<State> pq = new PriorityQueue<>(new Comparator<State>() {
            @Override
            public int compare(State o1, State o2) {
                return o1.distFromStart-o2.distFromStart;
            }
        });
        // 从起点 start 开始进行 BFS
        pq.offer(new State(start,0));

        while (!pq.isEmpty()){
            State curState= pq.poll();//获取当前结点信息
            int curId = curState.id;
            int curdist = curState.distFromStart;//获取当前结点距离起点距离

            if (curdist>distTo[curId]){
                continue;// 已经有一条更短的路径到达 curNode 节点了
            }
            // 将 curNode 的相邻节点装入队列
            for (int[] neighbor: graph[curId]
                 ) {
                int nextNodeId = neighbor[0];//取出邻结点id
                int distToNext=distTo[curId]+neighbor[1];//经过cur结点到邻结点这条路径的总长
                // 更新 dp table
                if (distTo[nextNodeId]>distToNext){
                    distTo[nextNodeId]=distToNext;
                    pq.offer(new State(nextNodeId,distToNext));
                }
            }

        }
        return distTo;
    }

    class State{
        int id; // 图节点的 id
        int distFromStart;// 从 start 节点到当前节点的距离

        State(int id,int distFromStart){
            this.id=id;
            this.distFromStart=distFromStart;
        }

    }
}

要点

  • 本题是单源寻找最短路径问题,使用DIJKSTRA 算法
  • 在迪杰斯特拉的基础上,加入最小堆,使得每次选择都是最小的权重,减少时间复杂度
  • 对于结点的状态,我们声名一个State类来表示,使得思路更加清晰
  • 有些题需要自己建表,对建表操作需要熟悉
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值