当前位置: 首页 > news >正文

算法笔记.spfa算法(bellman-ford算法的改进)

题目:(来源于AcWing)

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

请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 impossible

数据保证不存在负权回路。

输入格式

第一行包含整数 n 和 m。

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

输出格式

输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 impossible

数据范围

1≤n,m≤105,
图中涉及边长绝对值均不超过 10000。

输入样例:
3 3
1 2 5
2 3 -3
1 3 4
输出样例:
2

改进思路:

我们发现,只有一个节点的最短路径被更新之后,这个节点才可能被用来继续更新其出边的节点的最短路径。

代码实现:

 

#include<iostream>
#include<algorithm>
using namespace std;
#include<queue>
int n,m;
const int N = 100010;
int h[N],e[N],ne[N],w[N],idx;
int dist[N];
bool exi[N];//存储队列中是否已经有这个点了void add(int a,int b,int c)
{e[idx] = b;ne[idx] = h[a];w[idx] = c;h[a] = idx++;
}int spfa()
{queue<int> q;q.push(1);dist[1] = 0;exi[1] = true;while(q.size()){int nownode = q.front();q.pop();exi[nownode] = false;//取出该节点后更新exi数组//遍历出边for(int i = h[nownode];i!=-1;i=ne[i]){int tempnode = e[i];if(dist[tempnode] > dist[nownode]+w[i]){dist[tempnode] = dist[nownode]+w[i];if(!exi[tempnode]){q.push(tempnode);//只有本节点最短路被更新了,才需要更新这个节点的出边exi[tempnode] =true;}}}}if(dist[n] ==0x3f3f3f3f) return 0x3f3f3f3f;return dist[n];
}int main()
{fill(h,h+N,-1);//必须在存储边操作前初始化fill(dist,dist+N,0x3f3f3f3f);idx = 0;scanf("%d%d",&n,&m);while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}int t = spfa();if(t == 0x3f3f3f3f)cout <<"impossible"<<endl;else cout << t<<endl;return 0;
}

细节:

  1.  需要记录队列中是否已经存在该节点,如果已经存在,即便其被更新,也不用再添加它。

  2. 头指针h[]要在添加边之前初始化为-1.

spfa算法判断负环:

只需要添加数组count[],记录每个节点最短路径,上的边的数量,如果边数>n,说明存在负环。

spfa算法的性能: 

  1. 时间复杂度可以为O(n+m),但最坏时退化为O(nm)。
  2. 可以处理自环、重边、负环、允许边权为负。

 

http://www.xdnf.cn/news/112501.html

相关文章:

  • 要从给定的数据结构中提取所有的 itemList 并将其放入一个新的数组中
  • Python爬虫(3)HTML核心技巧:从零掌握class与id选择器,精准定位网页元素
  • mfc学习(一)
  • 基于whisper和ffmpeg语音转文本小程序
  • 【深度学习】#9 现代循环神经网络
  • 【C++】继承
  • 数据结构与算法实战:从理论到落地的深度探索
  • 原生微信小程序,canvas生成凭证,保存到手机
  • Java的进阶学习
  • 鲲鹏麒麟搭建Docker仓库
  • 海量聊天消息处理:ShardingJDBC分库分表、ClickHouse冷热数据分离、ES复合查询方案、Flink实时计算与SpringCloud集成
  • C++ RPC以及cmake
  • VBA技术资料MF300:利用Mid进行文本查找
  • 专家系统的一般结构解析——基于《人工智能原理与方法》的深度拓展
  • JBoltAI 赋能金融文档:基于 RAG 的基金招募说明书视觉增强方案
  • 分布式微服务架构,数据库连接池设计策略
  • 【框架学习】Spring AI-功能学习与实战(一)
  • node.js 实战——(Http 知识点学习)
  • 使用PyTorch如何配置一个简单的GTP
  • Framework.jar里的类无法通过Class.forName反射某个类的问题排查
  • FPGA上实现YOLOv5的一般过程
  • 机器学习特征工程中的数值分箱技术:原理、方法与实例解析
  • 看一看 中间件Middleware
  • mapbox高阶,高程影像、行政区边界阴影效果实现
  • 开源项目实战学习之YOLO11:ultralytics-cfg-datasets-lvis.yaml文件(五)
  • 长城杯铁人三项初赛-REVERSE复现
  • Linux常见指令介绍下(入门级)
  • 手搓雷达图(MATLAB)
  • Java24新增特性
  • C语言数据结构之顺序表