首页 > 编程语言 >数据结构与算法学习笔记----SPFA算法

数据结构与算法学习笔记----SPFA算法

时间:2024-12-19 10:28:20浏览次数:5  
标签:dist int SPFA ford ---- leq 算法 号点

数据结构与算法学习笔记----SPFA算法

@@ author: 明月清了个风
@@ first publish time: 2024.12.19

SPFA算法

这同样是一种单源最短路径算法,是队列优化的Bellman-ford算法,因此他能处理的情况和Bellman-ford算法一样,但是在一般情况下,时间复杂度更低,为 O ( m ) O(m) O(m), m m m为边数,最坏情况为 O ( n m ) O(nm) O(nm)。

基本思想

spfa的思想和bellman-ford算法一样。

可以发现bellman-ford算法在松弛操作时比较无脑,会遍历所有边进行遍历,但其实如果对于一个边 ( a , b ) (a,b) (a,b)来说,如果更新的话说明有 d i s t [ b ] > d i s t [ a ] + w ( a , b ) dist[b] > dist[a] + w(a,b) dist[b]>dist[a]+w(a,b),如果在这一轮中 d i s t [ a ] dist[a] dist[a]没有变,那么 d i s t [ b ] dist[b] dist[b]也不会变,因此这里可以考虑使用优化dijkstra的方法优化bellman-ford算法,也就是队列优化,具体的看代码吧,代码和dijkstra很像, 加入了比较详细的注释。

这里的无法到达判断和bellman-ford不一样,直接判断是否dist[n] == inf即可,因为每一次更新都肯定是能够从源点到达的点,而不是所有的边。

Acwing 853. 有边数限制的最短路

[原题链接](853. 有边数限制的最短路 - AcWing题库)

给定一个 n n n个点 m m m条边的有向图,图中可能存在重边和自环,边权可能为负数。

请你求出 1 1 1号点到 k k k号点的最多经过 k k k条边的最短距离,如果无法从 1 1 1号点走到 n n n号点,则输出 i m p o s s i b l e impossible impossible。

注意:图中可能出现负权回路。

输入格式

第一行包含三个整数 n n n, m m m, k k k。

接下来 m m m行,每行包含三个整数 x x x、 y y y、 z z z,表示存在一条从点 x x x到点 y y y的有向边,边长为 z z z。

输出格式

输出一个整数,表示 1 1 1号点到 n n n号点的最多经过 k k k条边的最短距离。

如果无法从 1 1 1号点走到 n n n号点,则输出 i m p o s s i b l e impossible impossible。

数据范围

1 ≤ n , k ≤ 500 1 \leq n,k \leq 500 1≤n,k≤500,

1 ≤ m ≤ 10000 1 \leq m \leq 10000 1≤m≤10000,

1 ≤ x , y ≤ n 1 \leq x, y \leq n 1≤x,y≤n,

图中涉及边长均不超过10000。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int N = 100010, inf = 0x3f3f3f3f;

int dist[N];
int h[N], w[N], e[N], ne[N], idx;
bool st[N];    // 用来记录点的距离是否被更新了,若距离更新则加入队列并置1.
int n, m;

void add(int a, int b, int c)  // 邻接表加边操作
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

int spfa()
{
    memset(dist, 0x3f, sizeof dist); // 初始化距离
    dist[1] = 0;
    
    queue<int> q;
    q.push(1);
    st[1] = true;   // 源点入队
    
    while(q.size())
    {
        int t = q.front();  // 取出队头
        q.pop();
        
        st[t] = false;  // 处理后置0
        
        for(int i = h[t]; i != -1; i = ne[i])   // 遍历出边,更新距离。
        {
            int j = e[i];
            if(dist[j] > dist[t] + w[i])    // 判断更新条件
            {
                dist[j] = dist[t] + w[i];
                if(!st[j])   // 若更新了但没在更新队列中,就加入队列。
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
    
    return dist[n];
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    
    for(int i = 0; i < m; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
    }
    
    int t = spfa();
    
    if(t == inf) puts("impossible");
    else cout << t << endl;
    
    return 0;
}

标签:dist,int,SPFA,ford,----,leq,算法,号点
From: https://blog.csdn.net/weixin_60278491/article/details/144578522

相关文章

  • 下载jupyter notebook。并且在自己配置的环境中打开指定文件夹。(超详细)
    之前一直用的pycharm,这次git上的代码是jupyternotebook的形式。因此要下载jupyternotebook,并且用之前在anaconda中配置好的环境,下面看一下详细步骤吧。1.打开anacondanavigater2.左上角选择环境,选择在自己配置好的环境中,然后点击install下载jupyternotebook。(我这是......
  • 如何下载本地WHL文件到指定环境
    1.打开anacondaprompt终端2.激活自己的环境。(输入activate环境名)3.指定到安装包下载好的目录下,比如我的目录如下4.输入pipinstall(文件名).whl   一定要加.whl!不然会出现如下报错!最后就安装成功了!四次报错分别是常见的错误(1.没有指定到whl的目录下2.没有加.......
  • 今日链表初识
    前言:链表是数据结构非常常见的一种,比如在java中LinkedList,数据库中的B+TREE都用到了链表。今天我们先来认识一下,什么是链表,以及一个简单的练习反转链表。什么是链表链表是一种每个节点不光可以存储当前节点数据,并且还会保存这一个节点的指针。如图:那如何使用java语言......
  • 【已解决】在Visual Studio里将应用与Microsoft Store关联时提示网络异常
    发布Windows应用时。在VisualStudio里点击"发布“,将应用与MicrosoftStore关联时,一直提示网络错误。查了一下论坛,发现之前也经常出现,但我是第一次遇到。不能就这样一直被卡着呀,研究了一下,还是有方法手动进行关联的。总结一下其实就两步:设置证书,更新Package.StoreAssoci......
  • 【MySQL】InnoDB存储引擎中的页
    目录1、背景2、页的组成3、各部分讲解【1】文件头部【2】页头部【3】最小记录和最大记录【4】行记录【5】空闲空间【6】页目录【7】文件尾部4、总结1、背景mysql中存储数据是存储引擎干的事,存储引擎存储数据的基本单位是页,我们往数据库插入表中的一条条记录就是存储......
  • GO 学习笔记之三 基础语法(11) 数据类型转换
    一、将字符串类型的数字转换为数字类型1)使用 strconv 包中的 Atoi 函数Atoi 函数用于将字符串转换为int。如果字符串不是合法的int表示,函数会返回错误。packagemainimport("fmt""strconv")funcmain(){str:="123"num,err:=strco......
  • NocoBase 本周更新汇总:优化移动端
    汇总一周产品更新日志,最新发布可以前往我们的博客查看。NocoBase目前更新包括的版本更新包括三个分支:main,next和develop。main:截止目前最稳定的版本,推荐安装此版本。next:包含即将发布的新功能,经过初步测试的版本,可能存在部分已知或未知问题。主要面向测试用户,用于收集反......
  • 蜜雪冰城涨价背后:如何优化茶饮行业成本控制与运营?
    12月17日,“蜜雪冰城多地涨价1元”的消息冲上热搜,引发了网友们的关注和热议。据财联社等媒体报道,广州多家蜜雪冰城门店在小程序上发布公告称,综合门店经营情况,12月16日起,本店堂食,小程序APP饮品(含冰淇淋系列)门市价加1元。面对媒体求证,蜜雪冰城官方客服表示,冰杯、零食、周边价格不变,......
  • RTL8211F以太网千兆RGMII开发板 使用说明
    深圳市飞录科技有限公司www.szfpga.com1.概述    RGMII 开发板主芯片是RTL8211FD。配套国产GOWIN的2AR-18和NR-9C的开发板,测试RGMII的千兆以太网数据发送和接收功能。  开发板的代码是基于MAC模式,通过循环发送计数器来判断包发送和接收是否正确。   2.操......
  • 向量新增的3种方式
    本文介绍向量检索服务如何通过控制台、SDK、API三种不同的方式新增向量。前提条件已开通向量检索服务。如未开通,请先开通服务。已创建Collection。控制台方式登录向量检索服务控制台。在左侧导航栏单击Cluster列表,选中需要新增向量的Collection,单击Collection......