题目:
851. spfa求最短路 - AcWing题库
输入样例:
3 3
1 2 5
2 3 -3
1 3 4
输出样例:
2
分析:
先去定义一个class 类似于c++里面的pair 里面有两个变量x, y 因为后面需要用优先队列来处理最短路问题需要指出比较x还是y 因此我们让这个pair类实现 Comparable 接口 实现里面的方法 去指出比较谁 按谁去比较
spfa的思路和dijkstra的代码基本上是一样的 但在st可逆不可以上进行了优化 spfa的st是可逆的,你只要出队列 就把你改为false 进来就改为true
SPFA算法不一样,它相当于采用了BFS,因此遍历到的结点都是与源点连通的,因此如果你要求的n和源点不连通,它不会得到更新,还是保持的0x3f3f3f3f。
里面st boolean类型的数组的作用是:表明这个点在(true) 不在(false) 优先队列里面, 要是在的话 我就不加进去了 不在的话 我在把这个点加进去
代码:
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;/*** @Title: spfa* @Author FindYou* @description:*/
public class spfa {public static int n, m;public static int[] h, ne, w, e, dis;public static boolean[] st;public static int idx;public static Queue<Pair> q = new PriorityQueue<>();public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();h = new int[m + 10];ne = new int[m + 10];w = new int[m + 10];e = new int[m + 10];dis = new int[m + 10];st = new boolean[n + 10];init(); // 初始化 要记得for(int i = 1; i <= m; ++ i ) {int a, b, c;a = sc.nextInt();b = sc.nextInt();c = sc.nextInt();add(a, b, c);}spfa();if(dis[n] == 0x3f3f3f3f) {System.out.println("impossible");} else {System.out.println(dis[n]);}}public static void add(int a, int b, int c) {e[idx] = b; // 当前这个点是 bw[idx] = c; // 这个的权值是cne[idx] = h[a];h[a] = idx ++ ;}public static void init() {idx = 0;for(int i = 1; i <= n; ++ i ) {h[i] = -1;dis[i] = 0x3f3f3f3f;}dis[1] = 0;}public static void spfa() {q.add(new Pair(0, 1)); // 0是距离 1是点了st[1] = true;while (q.size() != 0 ) {Pair t = q.poll();int pos = t.y; // 吧这个点给取出来了st[pos] = false; // 那么就标记为falsefor(int i = h[pos]; i != -1; i = ne[i]) {int j = e[i];if(dis[j] > dis[pos] + w[i]) {dis[j] = dis[pos] + w[i];if(!st[j]) {st[j] = true;q.add(new Pair(dis[j], j));}}}}}
}class Pair implements Comparable<Pair>{int x;int y;public Pair(int x, int y) {this.x = x;this.y = y;}public Pair() {}@Overridepublic int compareTo(Pair o) {if(this.x != o.x) {return this.x - o.x;} else {return this.y - o.y;}}
}