SPFA单源最短路径
来源:互联网 发布:网络选择软件 编辑:程序博客网 时间:2024/04/28 20:40
SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余松弛操作。前面说的Dijkstra算法虽然思想简单,优化也不难,但是如果面对含有负环的图来求解的话就无能为力了。并且从另一方面讲,即使图中没有负环,由于Dijkstra算法是基于结点的,而SPFA算法是基于边数的,所以说对于结点较少而边数较多(也就是稠密图)来说,无疑PriorityQueue+Dijkstra是最好的选择;而对于结点较多边数较少(也就是稀疏图)来说无疑SPFA最高效。
简单提一下SPFA算法思想:Bellman-Ford的升级版,使用一个队列来维护松弛过的结点,初始时将源节点加入队列,之后每次对队列进行出队列操作,并将出队列的这个结点对它的所有邻接节点进行松弛操作,并将松弛成功的结点加入到队列中(如果在队列中就不再添加),重复以上操作直到队列为空。另外判断图中是否存在负环:如果某一个结点进队列次数超过了n就说明存在负环。
对于稀疏图来说,SPFA的效率比PriorityQueue+Dijkstra的效率还略高,实现却比后者简单了许多。
实例:蓝桥杯ALGO-5"最短路"
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
1 2 -1
2 3 -1
3 1 2
-2
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
SPFA算法实现代码:
import java.util.HashMap;import java.util.Iterator;import java.util.PriorityQueue;import java.util.Queue;import java.util.Scanner;import java.util.Set;public class Spfa {static int nodeCount;static int edgeCount;static Node[] nodeArray;static int [] dist;static Queue<Integer> queue;static int max = 10000000;static class Node {private HashMap<Integer, Integer> map = null;public void addEdge(int end, int edge) {if (this.map == null) {this.map = new HashMap<Integer, Integer>();}this.map.put(end, edge);}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);nodeCount = sc.nextInt();edgeCount = sc.nextInt();queue = new PriorityQueue<Integer>();dist = new int[nodeCount + 1];nodeArray = new Node[nodeCount + 1];// nodeArray初始化for (int i = 0; i < nodeCount + 1; i ++) {nodeArray[i] = new Node();dist[i] = max;}dist[1] = 0;for (int i = 0; i < edgeCount; i ++) {int begin = sc.nextInt();int end = sc.nextInt();int edge = sc.nextInt();nodeArray[begin].addEdge(end, edge);}sc.close();long begin = System.currentTimeMillis();spfa();for (int i = 2; i < nodeCount + 1; i ++) {System.out.println(dist[i]);}long end = System.currentTimeMillis();System.out.println(end - begin + "ms");}private static void spfa() {queue.offer(1);while (!queue.isEmpty()) {int index = queue.poll();HashMap<Integer, Integer> hm = nodeArray[index].map;if (hm == null) {continue;}Set<Integer> s = hm.keySet();Iterator<Integer> it = s.iterator();while (it.hasNext()) {int num = it.next();if (dist[index] + hm.get(num) < dist[num]) {dist[num] = dist[index] + hm.get(num);if (!queue.contains(num)) {queue.offer(num);}}}}}}
- SPFA 单源最短路径
- SPFA单源最短路径
- 单源最短路径-spfa算法
- Spfa单源最短路径算法
- 【模板】Spfa单源最短路径
- 单源最短路径:SPFA算法
- 单源最短路径(spfa)
- [spfa]单源最短路径
- 单源最短路径的SPFA算法
- 单源最短路径SPFA算法-邻接矩阵
- pku 1151 Invitation Cards(单源最短路径 SPFA)
- 单源最短路径之SPFA算法实现
- 【图】单源最短路径bellman-ford和SPFA
- 图的单源最短路径SPFA算法
- 单源最短路径Dijkstra、BellmanFord、SPFA【模板】
- SPFA算法——单源最短路径
- 单源最短路径 ——SPFA算法
- SPFA算法 蓝桥杯 单源最短路径(含负权)
- 人力资源成熟度模型
- 【安卓】Content Provider 基础
- 几个vi命令
- Maven 学习
- android-async-http AsyncHttpClient介绍
- SPFA单源最短路径
- The Complete Guide to UML Diagram Types with Examples/ UML 图类型以及样例
- Android中当数据库需要更新时我们该怎么办?
- 【评论】为什么Scrum不行?
- Manifest.permission(对官方的资料进行的翻译)
- XCOPY
- 影记
- Ububtu安装中文输入法
- 开始刷leetcode day9: Maximum Depth of Binary Tree