AcWing 850. Dijkstra求最短路 II

这个跟之前的区别就在于这是一个稀疏图,点的数量会更多点

题目

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为非负值。

请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。

输入格式

第一行包含整数 n 和 m。

接下来 m 行每行包含三个整数 x,y,z表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式

输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 −1。

数据范围

1≤n,m≤1.5×10^5

图中涉及边长均不小于 0,且不超过 10000。

数据保证:如果最短路存在,则最短路的长度不超过 109。

输入样例:

复制代码
3 3
1 2 2
2 3 1
1 3 4

输出样例:

复制代码
3

代码与解析

java 复制代码
import java.util.*;

/**
 * Dijkstra算法求解最短路径(稀疏图)
 */
public class DijkstraShortestPath {
    static int n, m, idx, N = 1000010;
    static int[] h = new int[N], ne = new int[N], e = new int[N], w = new int[N], dis = new int[N];
    static boolean[] state = new boolean[N];  // 记录结点状态
    static Queue<Integer> q = new LinkedList<>();

    /**
     * 添加边
     *
     * @param a 边的起始结点
     * @param b 边的目标结点
     * @param c 边的权值
     */
    public static void add(int a, int b, int c) {
        e[idx] = b;
        ne[idx] = h[a];
        w[idx] = c;
        h[a] = idx++;
    }

    static class Pair {
        int first, second;

        public Pair(int a, int b) {
            this.first = a;
            this.second = b;
        }
    }

    /**
     * Dijkstra算法求解最短路径
     *
     * @return 最短路径的长度,如果不存在最短路径返回-1
     */
    public static int dijkstra() {
        // 初始化距离数组为无穷大
        Arrays.fill(dis, 0x3f3f3f3f);
        // 起始点距离为0
        dis[1] = 0;

        // 使用优先队列构建小根堆,按照距离值升序排列
        PriorityQueue<Pair> pq = new PriorityQueue<>(Comparator.comparingInt(p -> p.first));
        pq.offer(new Pair(0, 1));

        while (!pq.isEmpty()) {
            Pair p = pq.poll();
            int ver = p.second, distance = p.first;

            // 如果结点已经确定最短路径,继续下一轮循环
            if (state[ver]) continue;

            // 标记结点已访问
            state[ver] = true;

            // 遍历当前结点的邻接结点
            for (int i = h[ver]; i != -1; i = ne[i]) {
                int j = e[i];
                // 松弛操作:更新距离数组中的值
                if (dis[j] > dis[ver] + w[i]) {
                    dis[j] = dis[ver] + w[i];
                    // 将新的距离和结点编号加入优先队列
                    pq.offer(new Pair(dis[j], j));
                }
            }
        }

        // 如果终点的距离仍为初始值,说明不存在最短路径
        return dis[n] == 0x3f3f3f3f ? -1 : dis[n];
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        // 初始化图的邻接表,每个链表的初始值为无穷大
        Arrays.fill(dis, 0x3f3f3f3f);
        Arrays.fill(h, -1);
        for (int i = 0; i < m; i++) {
            int x = in.nextInt();
            int y = in.nextInt();
            int z = in.nextInt();
            add(x, y, z);
        }
        System.out.println(dijkstra());
    }
}
相关推荐
zopple2 小时前
常见的 Spring 项目目录结构
java·后端·spring
cjy0001113 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本4 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34164 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan5 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer6 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor3566 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor3566 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer7 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP7 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪