算法笔记.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.mzph.cn/bicheng/78425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

07 Python 字符串全解析

文章目录 一. 字符串的定义二. 字符串的基本用法1. 访问字符串中的字符2. 字符串切片3. 字符串拼接4. 字符串重复5.字符串比较6.字符串成员运算 三. 字符串的常用方法1. len() 函数2. upper() 和 lower() 方法3. strip() 方法4. replace() 方法5. split() 方法 四. 字符串的进阶…

Java集成Zxing和OpenCV实现二维码生成与识别工具类

Java集成Zxing和OpenCV实现二维码生成与识别工具类 本文将介绍如何使用Java集成Zxing和OpenCV库&#xff0c;实现二维码的生成和识别功能。识别方法支持多种输入形式&#xff0c;包括File对象、文件路径和Base64编码。 一、环境准备 添加Maven依赖 <dependencies><…

【专题刷题】二分查找(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

Java—ThreadLocal底层实现原理

首先&#xff0c;ThreadLocal 本身并不提供存储数据的功能&#xff0c;当我们操作 ThreadLocal 的时候&#xff0c;实际上操作线程对象的一个名为 threadLocals 成员变量。这个成员变量的类型是 ThreadLocal 的一个内部类 ThreadLocalMap&#xff0c;它是真正用来存储数据的容器…

Elasticsearch(ES)中的脚本(Script)

文章目录 一. 脚本是什么&#xff1f;1. lang&#xff08;脚本语言&#xff09;2. source&#xff08;脚本代码&#xff09;3. params&#xff08;参数&#xff09;4. id&#xff08;存储脚本的标识符&#xff09;5. stored&#xff08;是否为存储脚本&#xff09;6. script 的…

客户联络中心能力与客户匹配方式

在数字化时代&#xff0c;客户联络中心作为企业与客户沟通的核心枢纽&#xff0c;其服务能力与客户需求的精准匹配至关重要。随着客户期望的不断提升&#xff0c;传统的“一刀切”服务模式已难以满足个性化需求&#xff0c;如何通过智能化的手段实现服务能力与客户的高效匹配&a…

深入理解网络原理:UDP协议详解

在计算机网络中&#xff0c;数据的传输是通过各种协议实现的&#xff0c;其中用户数据报协议&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;作为一种重要的传输层协议&#xff0c;广泛应用于实时通信、视频流、在线游戏等场景。本文将深入探讨UDP协议的特性、…

vscode切换Python环境

跑深度学习项目通常需要切换python环境&#xff0c;下面介绍如何在vscode切换python环境&#xff1a; 1.点击vscode界面左上角 2.在弹出框选择对应kernel

【MCP Node.js SDK 全栈进阶指南】中级篇(4):MCP错误处理与日志系统

前言 随着MCP应用的规模和复杂性增长,错误处理与日志系统的重要性也日益凸显。一个健壮的错误处理策略和高效的日志系统不仅可以帮助开发者快速定位和解决问题,还能提高应用的可靠性和可维护性。本文作为中级篇的第四篇,将深入探讨MCP TypeScript-SDK中的错误处理与日志系统…

【Qt】文件

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 输入输出设备类 三&#xff1a;&#x1f525; 文件读写类 四&#xff1a;&#x1f525; 文件和目录信息类 五&…

代码随想录算法训练营第五十八天 | 1.拓扑排序精讲 2.dijkstra(朴素版)精讲 卡码网117.网站构建 卡码网47.参加科学大会

1.拓扑排序精讲 题目链接&#xff1a;117. 软件构建 文章讲解&#xff1a;代码随想录 思路&#xff1a; 把有向无环图进行线性排序的算法都可以叫做拓扑排序。 实现拓扑排序的算法有两种&#xff1a;卡恩算法&#xff08;BFS&#xff09;和DFS&#xff0c;以下BFS的实现思…

Qt实现语言切换的完整方案

在Qt中实现语言动态切换需要以下几个关键步骤&#xff0c;我将提供一个完整的实现方案&#xff1a; 一、准备工作 在代码中使用tr()标记所有需要翻译的字符串 cpp button->setText(tr("Submit")); 创建翻译文件 在.pro文件中添加&#xff1a; qmake TRANSLATION…

面试中被问到mybatis与jdbc有什么区别怎么办

1. 核心区别 维度JDBCMyBatis抽象层级底层API&#xff0c;直接操作数据库高层持久层框架&#xff0c;封装JDBC细节代码量需要手动编写大量样板代码&#xff08;连接、异常处理等&#xff09;通过配置和映射减少冗余代码SQL管理SQL嵌入Java代码&#xff0c;维护困难SQL与Java代…

用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)

摘要 一 介绍 问题一&#xff1a;以往的研究尝试利用相关图像之间的一致性&#xff0c;通过探索不同的共享线索[12, 13, 14]或语义连接[15, 16, 17]&#xff0c;来助力图像组内的共同显著目标检测&#xff08;CoSOD&#xff09;&#xff0c;什么意思&#xff1f; 一方面是探…

OpenCV 图形API(62)特征检测-----在图像中查找最显著的角点函数goodFeaturesToTrack()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 确定图像上的强角点。 该函数在图像或指定的图像区域内找到最显著的角点&#xff0c;如文献[240]中所述。 函数使用 cornerMinEigenVal 或 cor…

MySQL引擎分类与选择、SQL更新底层实现、分库分表、读写分离、主从复制 - 面试实战

MySQL引擎分类与选择、SQL更新底层实现、分库分表、读写分离、主从复制 - 面试实战 故事背景&#xff1a; 今天&#xff0c;我们模拟一场互联网大厂Java求职者的面试场景。面试官将针对MySQL的核心技术点进行提问&#xff0c;涵盖MySQL引擎分类与选择、SQL更新底层实现、分库…

如何确保微型导轨的质量稳定?

微型导轨在精密机械中扮演着至关重要的角色&#xff0c;它们不仅影响设备的性能&#xff0c;还决定了产品的寿命。那么&#xff0c;如何通过一些关键步骤来提高微型导轨的稳定性呢&#xff1f; 1、严格筛选供应商&#xff1a;选择具备高品质保证能力的供应商&#xff0c;确保原…

Golang编程拒绝类型不安全

简介 在 Go 中&#xff0c;标准库提供了多种容器类型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;这些容器默认是类型不安全的&#xff0c;即它们可以接受任何类型的值&#xff0c;这可能导致运行时错误。为了提升代码的类型安全性和可维护性&am…

什么是 JSON?学习JSON有什么用?在springboot项目里如何实现JSON的序列化和反序列化?

作为一个学习Javaweb的新手&#xff0c;理解JSON的序列化和反序列化非常重要&#xff0c;因为它在现代Web开发&#xff0c;特别是Spring Boot中无处不在。 什么是 JSON&#xff1f; 首先&#xff0c;我们简单了解一下JSON (JavaScript Object Notation)。 JSON 是一种轻量级的…

iOS/Android 使用 C++ 跨平台模块时的内存与生命周期管理

在移动应用开发领域,跨平台开发已经成为一种不可忽视的趋势。随着智能手机市场的持续扩张,开发者需要同时满足iOS和Android两大主流平台的需求,而这往往意味着重复的工作量和高昂的维护成本。跨平台开发的目标在于通过一套代码库实现多平台的支持,从而降低开发成本、加速产…