0
点赞
收藏
分享

微信扫一扫

Dijkstra 算法(Java)

少_游 2022-04-14 阅读 67
javaleetcode

例题:743. 网络延迟时间



输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出:2

 

// 邻接表
class Table{
    public int u;
    public List<Integer> v = new ArrayList<>();
    public List<Integer> w = new ArrayList<>();
    Table(int u){
        this.u = u;
    }
}

// 单个节点
class Node{
    public int u;
    public int dis;
    Node(int u, int dis){
        this.u = u;
        this.dis = dis;
    }
}

class Solution {
    Table [] tables; // 邻接表
    int [] dis; // 离起点的距离
    int [] vis; // 是否访问过
    int [] p; // 访问路径
    
    // 初始化
    public void init(int n){
        tables = new Table[n]; 
        dis = new int[n];
        vis = new int [n];
        p = new int[n];
        for(int i=0;i<n;i++){
            tables[i] = new Table(i);
        }
    }

    // dijkstra
    public void dij(int n, int k){
        PriorityQueue<Node> queue = new PriorityQueue<>(new Comparator<Node>()
        {
            @Override
            public int compare(Node a, Node b){
                return  a.dis - b.dis ;
            }
        }); // 优先队列选择最短的边
        for(int i=0;i<n;i++) dis[i] = Integer.MAX_VALUE; //设置初始距离
        dis[k] = 0;
        queue.offer(new Node(k, 0));
        int cnt = 0; // 统计松弛次数
        
        while(!queue.isEmpty()){
            Node node= queue.poll();
            int u = node.u;
            Table table = tables[u];
            

            if(vis[u]!=0) continue;
            vis[u] = 1;

            // 小优化
            cnt ++;
            if(cnt >= n) break;
            
            // 标记临近节点
            for(int i = 0;i< table.v.size() ;i++){
                int w = table.w.get(i);
                int v = table.v.get(i);


                if(dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w;
                    p[v] = u;
                    queue.offer(new Node(v, dis[v]));
                }
            }
        }

    }

    public int networkDelayTime(int[][] times, int n, int k) {
        // 构造邻接表
        init(n+1); // 初始化数组
        for(int i = 0;i < times.length;i++) {
            tables[times[i][0]].v.add(times[i][1]);
            tables[times[i][0]].w.add(times[i][2]);
        }
        dij(n+1, k); // 调用dijkstra
        Arrays.sort(dis); // 最短路径排序
        return dis[n-1]==Integer.MAX_VALUE?-1:dis[n-1];
    }
}
举报

相关推荐

0 条评论