SPFA 最短路算法

SPFA算法

1、什么是spfa算法?
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA一般情况复杂度是O(m)O(m) 最坏情况下复杂度和朴素 Bellman-Ford 相同,为O(nm)

2.算法步骤:

queue <– 1
while queue 不为空
(1) t <– 队头
queue.pop()
(2)用 t 更新所有出边 t –> b,权值为w
queue <– b (若该点被更新过,则拿该点更新其他点)

时间复杂度 一般:O(m) 最坏:O(nm)
n为点数,m为边数

3、spfa也能解决权值为正的图的最短距离问题,且一般情况下比Dijkstra算法还好

题目:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;



class Main {
	static int INF = 0x3f3f3f3f;
	static int N = 100000 + 5;
	static int[] head = new int[N];
	static int[] next = new int[N];
	static int[] vv = new int[N];
	static int[] ww = new int[N];
	static int idx = 0;
	static int[] dis = new int[N];
	static int n;
	// 当一个点放入queue就为true,取出就为false,防止队伍里面有重复元素,减小运行时间
	static boolean[] st = new boolean[N];

	public static void main(String[] args) throws IOException {
                //使用邻接链表存储别忘记初始化
		init();
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		String[] line = reader.readLine().split(" ");
		n = Integer.parseInt(line[0]);
		int m = Integer.parseInt(line[1]);
		for (int i = 1; i <= m; i++) {
			line = reader.readLine().split(" ");
			int x = Integer.parseInt(line[0]);
			int y = Integer.parseInt(line[1]);
			int z = Integer.parseInt(line[2]);
			add(x, y, z);
		}
		spfa();
	}

	private static void spfa() {
		// queue储存的是点
		Queue<Integer> queue = new LinkedList<Integer>();
		st[1] = true;
		queue.add(1);
		Arrays.fill(dis, INF);
		dis[1] = 0;
		while (!queue.isEmpty()) {
			int x = queue.poll();
			st[x] = false;
			for (int i = head[x]; i != -1; i = next[i]) {
				int j = vv[i];
				if (dis[j] > dis[x] + ww[i]) {
					dis[j] = dis[x] + ww[i];
					if (!st[j]) {
						st[j] = true;
						queue.add(j);
					}
				}
			}
		}
		if (dis[n] < INF / 2) {
			System.out.println(dis[n]);
		} else {
			System.out.println("impossible");
		}
	}

	private static void init() {
		// TODO Auto-generated method stub
		Arrays.fill(head, -1);
	}

	static void add(int x, int y, int w) {
		ww[idx] = w;
		vv[idx] = y;
		next[idx] = head[x];
		head[x] = idx++;
	}
}
posted @ 2022-04-07 16:36  思wu邪  阅读(99)  评论(0编辑  收藏  举报