输入样例:

3 3
1 2 5
2 3 -3
1 3 4

输出样例:

2

算法思路:

spfa最短路算法是对bellmanFord算法的优化,用于求单源最短路间的带负权的算法,一般时间复杂度为O(m),但最坏情况为O(nm)。spfa要求图中不能有负环(否则回无限循环)。

belllmanFord算法核心是 遍历每条边:dis[b] = min(dis[b], dis[a] + c),含义为:b到源点的最短路为当前b的最短路与将a点作为中间桥梁时,a点的最短路加上ab边的权值的最小值。由于bellmanFord算法每次从源点向外扩展一步,所以有很多边虽然遍历了,但没有意义,没有更新。即取决于dis[a]是否更新过,用宽搜优化。spfa算法将每次从源点发生变化的点入队,因为只有某些边缩小了,之后的边才会借此更新。

spfa算法步骤:(一初二迭三标四更)

  1. 初始化dis,qu,vis
  2. 只要队列中还有发生更新过的点就迭代
  3. 出队标记
  4. 更新点t的邻接边并选择性入队
  • spfa中vis数组的作用:标记某点是否在队列中,只有某点不在队列中,更新时遇到变化的点才加入队列,否则若如果队列中已经存在了该点,就不再入队了,否则会出现重复点,造成无意义的迭代,耗时。
  • dijkstra与spfa算法中vis数组的区别:前者是为了标记某点是否已经是从源点到当前点距离最小的点(是否已经用该点更新过其他点)。后者是为了标记该点是否在队列中存在。
  • dijkstra与spfa算法中使用队列的区别:前者使用的优先队列,元素只进不出,后者使用的普通队列;前者的使用队列是为了快速找出未被访问的点中距与源点最近的点,后者是为了记录更新过的点。若有负环,会一直更新,陷入死循环。
  • bellmanFord与spfa返回值判断时的区别:前者是统一迭代,无论是否两点间有路径,都会更新。而后者是通过邻接表的形式存储图,只会更新与源点相连的边。

Java代码:

import java.io.*;
import java.util.*;public class Main {static int n, m;static final int N = 100005;static int []e = new int[N];static int []ne = new int[N];static int []h = new int[N];static int []w = new int[N];static int idx;static int []dis = new int[N];static boolean []vis = new boolean[N];  //标记当前点是否在队列中,在时只需要更改dis数值,不在时才需要入队,否则重复判断耗时static final int INF = 0x3f3f3f3f;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] split = br.readLine().split(" ");n = Integer.parseInt(split[0]);m = Integer.parseInt(split[1]);Arrays.fill(h, -1);for(int i = 0; i < m; i++) {split = br.readLine().split(" ");int a = Integer.parseInt(split[0]);int b = Integer.parseInt(split[1]);int c = Integer.parseInt(split[2]);add(a, b, c);}spfa();}public static void spfa() {Arrays.fill(dis, INF);  // 1.初始化dis,qu,visdis[1] = 0;Queue<Integer> qu = new LinkedList<>(); qu.add(1);     // 1号点距离更新了,其出度的点都会伴随着更新vis[1] = true; // 1号点已在队列中while(!qu.isEmpty()) {  // 2.只要队列中还有发生更新过的点就迭代int t = qu.poll();  //3.出队标记vis[t] = false;     // 标记队列中不存在的点tfor(int i = h[t]; i != -1; i = ne[i]) { //  4.1更新点t的邻接边int j = e[i];if(dis[j] > dis[t] + w[i]) {dis[j] = dis[t] + w[i];if(!vis[j]) {    // 4.2若更新后的点队列中不存在则入队qu.add(j);vis[j] = true;}}}}if(dis[n] == INF) System.out.println("impossible"); // 路径不通的边不会更新,只需判断等于inf即可else System.out.println(dis[n]);}public static void add(int a, int b, int c) {e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx++;}
}

851. spfa求最短路 Java题解 (spfa)相关推荐

  1. AcWing 851. spfa求最短路(解决负边权最短路)

    题目链接 https://www.acwing.com/problem/content/853/ 思路 就是SPFA求最短路的模板,其思路大概是我们要更新所有能被松弛的边,然后更新松弛的边的边,然后就 ...

  2. 蓝桥杯最短路(java过)spfa单源最短路算法

    spfa 百度百科上spfa的思路为:动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最 ...

  3. SPFA求最短路——Bellman-Ford算法的优化

    SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE), ...

  4. SPFA算法求最短路

    AcWing 851. spfa求最短路 题目 https://www.acwing.com/problem/content/submission/853/ 给定一个 n 个点 m 条边的有向图,图中 ...

  5. 最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中)

    文章目录 第一类:单源最短路 一 所有边权都是正数(Dijkstra) 朴素版Dijkstra(稠密图) 堆优化版Dijkstra(稀疏图) 二 存在负权边(BF和SPFA) 第二类:多源汇最短路(F ...

  6. 算法基础课-搜索与图论-spfa-AcWing 852. spfa判断负环:spfa求负环板子

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: dist[x] 表示从源点到x点的最短距离. spfa算法求最短路的算法步骤: 初始化一个队列,将起点入队. 取出队头元素t,遍历它 ...

  7. p3371 单源最短路径(弱化版)-java题解-最短路

    弱化版传送门: P3371 [模板]单源最短路径(弱化版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通 ...

  8. 算法提高课-图论-负环-AcWing 904. 虫洞:spfa求负环裸题

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 负环:负环是这样的一个环,该环上的边权之和是负数. 存在负环的话,会对我们求最短路造成障碍,因为绕着这个负环转无数次,最短路越来越小 ...

  9. 【最短路】【SPFA】单源最短路径 (luogu 3371)

    单源最短路径 luogu 3371 题目大意: 求出一个点到其他点的最短路 原题: 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 ...

最新文章

  1. mongodb重命名集合、数据库
  2. Scratch青少年编程能力等级测试模拟题(三级)
  3. 仅剩一周!!CSDN年终大放血!人人有份的大奖你确定不来?
  4. android广播过滤器.*,android – BroadcastReceiver与多个过滤器或多个BroadcastReceivers?...
  5. java反射机制知识_Java反射机制讲解,程序员必须掌握的知识点
  6. python matplotlib散点图-Matplotlib scatter绘制散点图的方法实现
  7. python语法基础及if、while、for等语句介绍
  8. 公众号质量改进调查问卷
  9. 国外AI界牛人主页 及资源链接
  10. apache spark_Apache Spark:更改架构之前必须解决的5个陷阱
  11. webstorm 10.0.4 注册码
  12. Oracle Partition By 的使用
  13. npm收录了哪些包_使用VS Code轻松找到npm软件包中的漏洞(Vuln Cost)
  14. 我成功通过PMP考试的经验与体会
  15. “互联网+”大学生创新创业大赛项目策划书
  16. 操作系统安全与系统攻击
  17. 将jar文件安装为系统服务
  18. win10底部任务栏无响应解决办法
  19. 超分辨率重建——关于YIQ空间
  20. 百度云盘停止服务器,又一家网盘关闭!不要再问为什么百度网盘要收费了

热门文章

  1. 第十二届江苏省园艺博览会设计征集大赛获奖信息公示
  2. Foxmail发送邮件乱码的临时解决办法
  3. ADC芯片参数定义及选型指南
  4. 戴森球计划 超级计算机,更新详情 - 科幻游戏 戴森球计划 - 摩点
  5. 如何用链脉智能名片玩转微信裂变营销
  6. php 元素 拖拉,Draggable Elements 元素拖拽功能实现代码_javascript技巧
  7. JavaScript学习笔记1
  8. 需要使用cacti检测一台linux,部署cacti监控windows linux
  9. 机器学习算法:基于鸢尾花(iris)数据集的数据可视化 (200+收藏)
  10. java导出doc和docx