Dijkstra-leetcode 743.网络延迟时间

743.网络延迟时间

N 个网络节点,标记为 1N

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

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

示例:

img

输入:times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
输出:2

注意:

  1. N 的范围在 [1, 100] 之间。
  2. K 的范围在 [1, N] 之间。
  3. times 的长度在 [1, 6000] 之间。
  4. 所有的边 times[i] = (u, v, w) 都有 1 <= u, v <= N0 <= w <= 100

思路:

信号的传递走的是最短路径,题目要求所有节点都收到信号所需时间,就需要找到最后收到信号的节点。

可以看作从节点K开始,到其他节点的所有最短路径中最长的那一条。

找最短路径使用Dijkstra算法,找到从K开始到其他节点的最短路径,最后从这些最短路径中找出最长的一条返回即可


class Solution {
    int INF = (int)Double.POSITIVE_INFINITY;    //INF表示无穷大
    public int networkDelayTime(int[][] times, int N, int K) {
        int[][] matrix = new int[N+1][N+1];	//表示题目节点与边信息的邻接矩阵
        int[] dis = new int[N+1];   //储存K到其他节点最短路径
        int[] book = new int[N+1];  //记录已经找到最短距离的节点
        for(int i=0;i<N+1;i++){
            for(int j=0;j<N+1;j++){
                matrix[i][j] = INF;		//初始化邻接矩阵
            }
        }
        for(int i=0;i<times.length;i++){
            matrix[times[i][0]][times[i][1]] = times[i][2];	//通过题目所给信息初始化邻接矩阵
        }
        for(int i=1;i<N+1;i++){
            dis[i] = matrix[K][i];		//根据邻接矩阵为dis赋初值,表示从K能到达的节点的节点距离
        }
        book[K] = 1;    //初始节点置为1
        dis[K] = 0;		//K到K的距离为0
        for(int i=1;i<N+1;i++){
            int min = INF;	
            int u = -1;  //Q中最短结点
            for(int j=1;j<N+1;j++){ //找到从K出发能到达的最近的节点
                if(book[j] == 0 && dis[j] < min ){
                    min = dis[j];
                    u = j;
                }
            }
            if(u==-1){
                continue;
            }
            book[u] = 1;    //将最短节点标记为已找到
            for(int k=1;k<N+1;k++){     //对U的所有出边进行松弛
                if( matrix[u][k] < INF ){	//只有U能到达的节点才会进入循环
                    if(dis[k] > dis[u] + matrix[u][k]){	//如果通过U中转比K直接到新节点路径短
                        dis[k] =  dis[u] + matrix[u][k];	//修改最短距离
                    }
                }
            }
        }
        int ans = -1;
        for(int i=1;i<N+1;i++){	//遍历dis,如果还有K到其他节点的距离为INF,表示不能到达,返回-1
            if(dis[i] == INF)	
                return -1;
            ans = Math.max(ans,dis[i]);
        }
        return ans;	//返回到其他节点的最远距离
    }
}

堆优化版本

class Solution {
    int INF = (int)Double.POSITIVE_INFINITY;    //无穷大
    public int networkDelayTime(int[][] times, int N, int K) {
        Queue<Node> queue = new PriorityQueue<>(new MyCompare());	//优先队列,类型为Node
        int[][] matrix = new int[N+1][N+1];	//邻接矩阵
        int[] dis = new int[N+1];   //储存起点K到其他节点最短距离
        int[] book = new int[N+1];  //记录已经找到最短距离的节点
        for(int i=0;i<N+1;i++){		//初始化
            dis[i] = INF;
            for(int j=0;j<N+1;j++){
                matrix[i][j] = INF;
            }
        }
        for(int i=0;i<times.length;i++){
            matrix[times[i][0]][times[i][1]] = times[i][2];
        }
        dis[K] = 0;		    
        queue.add(new Node(K,0));	  //将起点入队   
        while( !queue.isEmpty() ){
            Node temp = queue.poll();	    //取出队列中距离起点最近的节点 u
            int u = temp.n;
            if( book[u] == 1 )		
                continue;
            book[u] = 1;		//因为节点u已经是离起点最近的节点,所以标记为已找到最小路径
            for(int i=1;i<N+1;i++){		
                if( book[i] == 0 && matrix[u][i] != INF){//遍历所有未找到最小路径的节点	
                    if(dis[i] > dis[u] + matrix[u][i]){	//判断是否能通过u进行松弛	
                        dis[i] = dis[u] + matrix[u][i];		
                        queue.add(new Node(i,dis[i]));		
                    }
                }
            }
        }
        int ans = -1;
        for(int i=1;i<N+1;i++){		//处理结果
            if(dis[i] == INF)
                return -1;
            ans = Math.max(ans,dis[i]);
        }
        return ans;
    }
}

class MyCompare implements Comparator<Node>{    //优先队列比较规则

    public int compare(Node n1,Node n2){
        if( n1.step > n2.step ){
            return 1;
        }else{
            return -1;
        }
    }

}

class Node{    //优先队列数据元素
    int n;    //节点编号
    int step;    //距离起点的距离
    public Node(int a,int b){
        n = a ;
        step = b;
    }
}

理论上堆优化的写法应该比朴素写法快一些,但是提交的时候反而慢一些....暂时不知道原因

posted @ 2020-05-03 16:23  ELAIRS  阅读(455)  评论(0编辑  收藏  举报