题目:
输入样例:
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; // 当前这个点是 b
w[idx] = c; // 这个的权值是c
ne[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; // 那么就标记为false
for(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() {
}
@Override
public int compareTo(Pair o) {
if(this.x != o.x) {
return this.x - o.x;
} else {
return this.y - o.y;
}
}
}