堆优化的Dijkstra算法

堆优化的Dijkstra算法

传统Dijkstra,在选取中转节点时,是遍历取当前最小距离节点,但是其实可利用优先队列Priority_queue优化查找过程,将时间复杂度从O((V+E)lgV)O(V2+E) 降低为O((V+E)lgV))

堆优化细节:

堆优化的主要思想就是使用优先队列来代替距起点最近元素的查找。

优先队列数据类型应该包含当前结点编号和当前节点与起点的距离

模板

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;
    }
}
        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];  //记录已经找到最短距离的节点
        dis[K] = 0;		//初始化起点到起点距离为0
        queue.add(new Node(K,0));		//将起点入队 
        while( !queue.isEmpty() ){
            Node temp = queue.poll();	//取出队列中距离起点最近的节点 u
            int u = temp.n;
            if( book[u] == 1 )		//如果节点u已存在最小路径,就continue
                continue;
            book[u] = 1;		//因为节点u已经是离起点最近的节点,所以标记为已找到最小路径
            for(int i=1;i<N+1;i++){		//遍历所有未找到最小路径的节点
                if( book[i] == 0 && matrix[u][i] != INF){	//当节点u能到达节点i时;
                    if(dis[i] > dis[u] + matrix[u][i]){		//如果通过节点u到节点i比直接从起点
                        dis[i] = dis[u] + matrix[u][i];		//到节点i距离更短,就进行松弛;
                        queue.add(new Node(i,dis[i]));		//将更新后的节点i的值加入队列
                    }
                }
            }
        }
		//dis数组中保存了结果,dis[i]表示从起点到i的最短路径


例题:

743. 网络延迟时间

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