SPFA 算法:实现原理及其应用

这篇具有很好参考价值的文章主要介绍了SPFA 算法:实现原理及其应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

SPFA算法,全称为Shortest Path Faster Algorithm,是求解单源最短路径问题的一种常用算法,它可以处理有向图或者无向图,边权可以是正数、负数,但是不能有负环。

二、SPFA 算法

1、SPFA算法的基本流程

1. 初始化

首先我们需要起点s到其他顶点的距离初始化为一个很大的值(比如9999999,像是 JAVA 中可以设置 Integer.MAX_VALUE 来使),并将起点s的距离初始化为0。同时,我们还需要将起点s入队。

spfa,算法,算法,java,图论

2. 迭代

每次从队列中取出一个顶点u,遍历所有从u出发的边,对于边(u,v)(其中v为从u可以到达的顶点),如果s->u->v的路径长度小于s->v的路径长度,那么我们就更新s->v的路径长度,并将v入队。

spfa,算法,算法,java,图论

3. 循环

不断进行步骤2,直到队列为空。

4. 判断

最后,我们可以得到从起点s到各个顶点的最短路径长度,如果存在无穷小的距离,则说明从起点s无法到达该顶点。

其次,需要注意的是,SPFA算法中存在负环问题。如果存在负环,则算法会陷入死循环。因此,我们需要添加一个计数器,记录每个点进队列的次数。当一个点进队列的次数超过图中节点个数时,就可以判定存在负环。

2、代码详解

以下是使用Java实现 SPFA算法的代码,其中Graph类表示有向图或无向图,Vertex类表示图中的一个顶点,Edge类表示图中的一条边。文章来源地址https://www.toymoban.com/news/detail-716927.html

import java.util.*;

class Graph {
      // 图
    private List<Vertex> vertices;  // 顶点集

    public Graph() {
   
        vertices = new ArrayList<Vertex>();
    }

    public void addVertex(Vertex v) {
      // 添加顶点
        vertices.add(v);
    }   // 添加顶点

    public List<Vertex> getVertices() {
    // 返回顶点
        return vertices;
    }   // 获取顶点集
}

class Vertex {
     // 点
    private int id; // 点 id
    private List<Edge> edges;   // 连接到该顶点的边
    private int distance;   // 从源顶点到该顶点的最短距离,MAX_VALUE init
    private boolean visited;    // 在图的遍历过程中是否访问过该顶点,false init

    public Vertex(int id) {
   
        this.id = id;
        edges = new ArrayList<Edge>();
        distance = Integer.MAX_VALUE;
        visited = false;
    }

  

到了这里,关于SPFA 算法:实现原理及其应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【图论】SPFA求负环

    算法提高课笔记 负环 :环上权值之和是负数 求负环的常用方法 基于SPFA 统计每个点入队次数,如果某个点入队n次,则说明存在负环(完全等价于Bellman-Ford算法) 统计当前每个点的最短路中所包含的边数,如果某点的最短路包含的边数大于等于n,则说明存在负环 玄学结论:

    2024年02月09日
    浏览(16)
  • 图论 - 最短路(Dijkstra、Bellman-Ford、SPFA、Floyd)

    单源:在边权正数时,稠密图用朴素Dijkstra,稀疏图用堆优化Dijkstra;存在负权边时,一般用SPFA,但是如果限制在k步内,则用Bellman-Ford。多源:只有Floyd,这个由于时间复杂度太高,在算法比赛中很少遇见。 1.问题描述 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自

    2024年04月14日
    浏览(12)
  • 【蓝桥杯--图论】Dijkstra、Ballman-Ford、Spfa、Floyd

    今日语录: 每一次挑战都是一次成长的机会 如上所示即为做题时应对的方法 引用与稠密图,即mn^2

    2024年01月23日
    浏览(34)
  • 【最短路算法】SPFA

    在计算机科学的世界里,算法就像是星空中的繁星,各自闪烁着智慧的光芒。它们沉默而坚定,像是一群不语的哲人,默默地解答着世界的问题。 算法的步骤,如同优美的诗行,让复杂的问题在流转的字符中得以释放。它们如同山间清泉,从一座山峰流淌到另一座山峰,涤荡

    2024年02月14日
    浏览(11)
  • SPFA算法详解

    SPFA 算法是Bellman-ford算法的 队列优化 算法的别称,通常用于求 含负权边的单源最短路径 ,以及 判负权环 。 前置知识:Bellman-ford算法详解_真的没事鸭的博客-CSDN博客 SPFA算法其实就是在Bellman-ford算法基础上的优化。Bellman-ford算法看起来比较傻,每次迭代的话是遍历所有边来

    2023年04月23日
    浏览(21)
  • 「学习笔记」SPFA 算法的优化

    与其说是 SPFA 算法的优化,倒不如说是 Bellman-Ford 算法的优化。 将原本的 bfs 改为 dfs,在寻找负环时可能有着更高效的效率,但是最坏复杂度为指数级别。 将 queue 换成 deque ,判断与队首元素的 dis 的大小,小的就放队首,大的就放队尾。 将 queue 换成 deque ,判断一个点是否

    2024年02月02日
    浏览(42)
  • SPFA + 链式前向星建图【附Java模板】

                                                                                 SPFA算法是什么?它能解决什么样的问题?           🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客🎐 🐳 数据结构与算法专栏的文章

    2024年02月06日
    浏览(16)
  • 最短路径算法( Dijkstra + Bellman-Ford + SPFA + Floyd)

       文章目录 一、Dijkstra 算法 1、1 朴素版Dijkstra算法 1、1、1 Dijkstra求最短路 I 1、1、2 题解关键思路与与解答 1、2 堆优化版Dijkstra算法 1、2、1 Dijkstra求最短路 II 1、2、2 题解关键思路与答案 二、Bellman-Ford 算法 2、1 Bellman-Ford算法求有边数限制的最短路 2、1、1 题目描述 2、

    2023年04月08日
    浏览(9)
  • 第十八章 SPFA算法以及负环问题(利用dijkstra推导出该算法,超级详细!!)

    我们回顾一下之前的dijkstra算法的证明过程。如果大家没看过之前的dijkstra算法的简易证明的话,作者在这里建议先去看一下。 传送门: 第十六章 Dijkstra算法的讲解以及证明(与众不同的通俗证明) 那么假设你已经看过这篇文章,我们发现,我们将每次松弛操作后的最小距离

    2024年02月02日
    浏览(25)
  • SPFA之差分约束

    求不等式的可行解 求 最大 值与 最小 值 (重点) 步骤: 将每个不等式 x i ≤ x j + c k x_ile x_j + c_k x i ​ ≤ x j ​ + c k ​ ,转化为一条从 x j x_j x j ​ 到 x i x_i x i ​ 的一条长度为 c k c_k c k ​ 的边 找到一个超级源点,使得该源点一定可以遍历到所有边 从源点求一遍单源最短

    2024年02月13日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包