问题

解决这样一类问题,起点确定的,可以有重边和自环的,各边权都为正数的稀疏图的最短路问题

要素

  1. h[], idx, e[], ne[], w[] 用邻接表存储图
  2. st[]记录已经确定最短距离的点
  3. dist[] 存储每个点到起点的最短距离

    思路

    相较与朴素版Dijkstra每次遍历一遍所有节点找到当前距起点最近的点,堆优化版优化了这一做法,有点类似bfs,每次的队头元素如果还没加入st的话,一定是当前距起点最近的点,用该点更新其临点到起点的距离并入队,因为是优先队列,每次加入一个元素会更新队列使得最小元素出现在队头。

时间复杂度:手写堆:O(M*logN)优先队列O(M*logM) = O(MlogN2) = O(MlogN)
所以没必要手写堆
本质:贪心

模板

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×105
图中涉及边长均不小于 0,且不超过 10000。
输入样例:

  1. 3 3
  2. 1 2 2
  3. 2 3 1
  4. 1 3 4

输出样例:

  1. 3
  1. import java.util.*;
  2. public class Main {
  3. static final int N = 150010;
  4. static int[] h = new int[N], e = new int[N], ne = new int[N], w = new int[N];
  5. static int[] dist = new int[N];
  6. static boolean[] st = new boolean[N];
  7. static int n, m;
  8. static int idx = 0;
  9. public static void main(String[] args) {
  10. Scanner sc = new Scanner(System.in);
  11. n = sc.nextInt();
  12. m = sc.nextInt();
  13. Arrays.fill(h, -1);
  14. for (int i = 0; i < m; i++) {
  15. int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
  16. add(a, b, c);
  17. }
  18. dijkstra(1, dist);
  19. if (dist[n] == 0x3f3f3f3f)
  20. System.out.println(-1);
  21. else
  22. System.out.println(dist[n]);
  23. }
  24. static void dijkstra(int start, int[] dist) {
  25. Arrays.fill(dist, 0x3f3f3f3f);
  26. dist[start] = 0;
  27. Arrays.fill(st, false);
  28. PriorityQueue<int[]> q = new PriorityQueue<>((o1, o2) -> (o1[1] - o2[1]));
  29. q.offer(new int[]{start, 0});
  30. while (!q.isEmpty()) {
  31. int[] p = q.poll();
  32. int u = p[0], d = p[1];
  33. if (st[u]) continue;
  34. st[u] = true;
  35. dist[u] = d;
  36. for (int i = h[u]; i != -1; i = ne[i]) {
  37. int j = e[i], ww = w[i];
  38. q.offer(new int[]{j, ww + d});
  39. }
  40. }
  41. }
  42. static void add(int a, int b, int c) {
  43. e[idx] = b;
  44. w[idx] = c;
  45. ne[idx] = h[a];
  46. h[a] = idx++;
  47. }
  48. }