搜索与图论——bellman—ford算法、spfa算法求最短路

bellman-ford算法 时间复杂度O(nm)

在一般情况下,spfa算法都优于bf算法,但遇到最短路的边数有限制的题时,只能用bf算法

bf算法和dijkstra很像

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 510,M = 10010;

int n,m,k;
int dist[N],backup[N]; //backup备份数组

struct Edge{
    int a,b,w;
}Edge[M]; //存所有边

int bellman_ford(){
    memset(dist,0x3f,sizeof dist);
    dist[1] = 0;
    for(int i = 0;i < k;i ++ ){
        memcpy(backup,dist,sizeof dist); //备份dist,不会出现串联情况
        for(int j = 0;j < m;j ++ ){
            int a = Edge[j].a,b = Edge[j].b,w = Edge[j].w;
            dist[b] = min(dist[b],backup[a] + w);
        }
    }
    if(dist[n] > 0x3f3f3f3f / 2) return 0;
    else return dist[n];
}

int main(){
    cin >> n >> m >> k;
    for(int i = 0;i < m;i ++ ){
        int a,b,w;
        cin >> a >> b >> w;
        Edge[i] = {a,b,w};
    }
    int t = bellman_ford();
    if(!t) cout << "impossible" << endl;
    else cout << t << endl;
    return 0;
}

spfa算法 时间复杂度一般O(m), 最坏O(nm)

基本上单源最短路都可以用spfa来解决

spfa的核心优化思路是:拿我更新过的点来更新别人。一个点如果没有被更新过的话,拿它来更新别人一定是没有效果的,只有该点变小了,该点后面的点才会变小

spfa代码和堆优化dijkstra特别像

spfa算法求最短路

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>

using namespace std;

typedef pair<int,int> PII;

const int N = 150010;

int n,m;
int h[N],w[N],e[N],ne[N],idx;
int dist[N];
bool vis[N];

int add(int a,int b,int c){
    e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx,idx ++ ;
}

int spfa(){
    memset(dist,0x3f,sizeof dist);
    dist[1] = 0;
    queue<int> q; //队列里存的是变小的a
    q.push(1);
    vis[1] = true;
    while(q.size()){
        int t = q.front();
        q.pop();
        vis[t] = false;
        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(!vis[j]){
                    q.push(j);
                    vis[j] = true;
                }
            }
        }
    }
    if (dist[n] == 0x3f3f3f3f) return 0;
    return dist[n];
}

int main(){
    cin >> n >> m;
    memset(h,-1,sizeof h);
    while(m -- ){
        int x,y,z;
        cin >> x >> y >> z;
        add(x,y,z);
    }
    int t = spfa();
    if(!t) cout << "impossible" << endl;
    else cout << t << endl;
    return 0;
}

spfa算法求负环

spfa算法可以求出负环用的是抽屉原理,即把多于n+1个的物体放到n个抽屉里,则至少有一个抽屉里的东西不少于两件。

代码在spfa求最短路的模板上稍加改动即可

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>

using namespace std;

typedef pair<int,int> PII;

const int N = 150010;

int n,m;
int h[N],w[N],e[N],ne[N],idx;
int dist[N],cnt[N];
bool vis[N];

int add(int a,int b,int c){
    e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx,idx ++ ;
}

bool spfa(){
    queue<int> q;
    for(int i = 1;i <= n;i ++ ){ //由于存在的负环1号点可能走不到,所以要把每一个点都推进队列
        vis[i] = true;
        q.push(i);
    }
    vis[1] = true;
    while(q.size()){
        int t = q.front();
        q.pop();
        vis[t] = false;
        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];
                cnt[j] = cnt[t] + 1; //最重要的一步,如果j被更新了最短路,那么意味着j点的cnt是前一个点t+1条边达到的
                if(cnt[j] >= n) return true;
                if(!vis[j]){
                    q.push(j);
                    vis[j] = true;
                }
            }
        }
    }
    return false;
}

int main(){
    cin >> n >> m;
    memset(h,-1,sizeof h);
    while(m -- ){
        int x,y,z;
        cin >> x >> y >> z;
        add(x,y,z);
    }
    if(spfa()) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/500634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华清远见STM32U5开发板助力2024嵌入式大赛ST赛道智能可穿戴设备及IOT选题项目开发

第七届&#xff08;2024&#xff09;全国大学生嵌入式芯片与系统设计竞赛&#xff08;以下简称“大赛”&#xff09;已经拉开帷幕&#xff0c;大赛的报名热潮正席卷而来&#xff0c;高校电子电气类相关专业&#xff08;电子、信息、计算机、自动化、电气、仪科等&#xff09;全…

用navicat进行mysql表结构同步

用navicat进行mysql表结构同步 前言新增一个列然后进行表结构同步删除一个列然后进行表结构同步把Int列转成TinyInt列&#xff0c;看数字溢出的情况下能不能表结构同步总结 前言 从同事那边了解到还能用navicat进行表结构同步&#xff0c;他会在发布更新的时候&#xff0c;直接…

Reasoning on Graphs: Faithful and Interpretable Large Language Model Reasonin

摘要 大型语言模型(llm)在复杂任务中表现出令人印象深刻的推理能力。然而&#xff0c;他们在推理过程中缺乏最新的知识和经验幻觉&#xff0c;这可能导致不正确的推理过程&#xff0c;降低他们的表现和可信度。知识图谱(Knowledge graphs, KGs)以结构化的形式捕获了大量的事实…

在哪买国外服务器便宜?

在哪买国外服务器便宜&#xff1f;在寻找便宜且可靠的国外服务器商家时&#xff0c;我们需要考虑多个因素&#xff0c;包括价格、性能、可靠性、技术支持和扩展性等。下面是一些备受推崇的便宜国外服务器商家。 Amazon Web Services (AWS)。作为全球最大的云服务提供商之一&am…

WebSocket 详解-小案例展示

简介&#xff1a;Websocket是一种用于H5浏览器的实时通讯协议&#xff0c;可以做到数据的实时推送&#xff0c;可适用于广泛的工作环境&#xff0c;例如客服系统、物联网数据传输系统&#xff0c;该测试工具可用于websocket开发初期的测试工作。 文章末尾有此案例的完整源代码。…

从vivo X Fold3看vivo“质”变

撰文 | 何玺 排版 | 叶媛 vivo的气质变了&#xff01;虽然依旧内敛、低调&#xff0c;但更自信、从容&#xff0c;气场也更强大。这是玺哥在本次vivo X Fold3系列新品发布会上的一个直观感受。 是什么改变了vivo的气质&#xff1f;产品&#xff1f;技术&#xff1f;又或是其他…

基于STC12C5A60S2系列1T 8051单片机通过单个按键单击次数实现开关机应用

基于STC12C5A60S2系列1T 8051单片机通过单个按键单击次数实现开关机应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍基于STC12C5A60S2系列1T 8051单片机通过单个按…

代码随想录算法训练营第二十四天(回溯1)|77. 组合(JAVA)

文章目录 回溯理论基础概念类型回溯模板 77. 组合解题思路源码 回溯理论基础 概念 回溯是递归的副产品&#xff0c;本质上是一种穷举 回溯解决的问题可以抽象为一种树形结构 类型 回溯主要用来解决以下问题 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问…

eNSP综合实验(PPP认证、VPN配置、RIP协议、NAT)

题目如上 第一步:配置IP地址 ip分配如下图所示 开始配置IP(PC省略&#xff09; R1&#xff1a; [R1]undo [R1]undo in [R1]undo info-centere [R1]undo info-center e [R1]undo info-center enable Info: Information center is disabled. [R1]int g0/0/0 [R1-Gigabit…

2024年MathorCup数学建模思路A题B题C题D题思路分享

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

蓝桥杯-岛屿个数

solution 数1的块数题&#xff0c;加了内岛不计入的小限制&#xff0c;以及输入数据间没有空格&#xff0c;不是矩阵形式的整数输入。 判断是否是子岛屿&#xff1a;如果该岛屿有边缘部分或者可以通过外海走到边缘部分说明不是子岛屿 #include<iostream> #include<…

蓝桥备赛——堆队列

AC code import os import sys import heapq a [] b [] n,k map(int,input().split())for _ in range(n):x,y map(int,input().split())a.append(x)b.append(y) q []# 第一种情况&#xff1a;不打第n个怪兽# 将前n-1个第一次所需能量加入堆 for i in range(n-1):heapq.h…

科普——芯片的市场价格

以前以为进口的芯片会很贵&#xff0c;其实不然&#xff0c;均在很低&#xff0c;粗略找了几个&#xff0c;批发价格在50元上下 厂商型号&#xff1a;STM32F103RCT7 品牌名称&#xff1a;ST(意法半导体) 元件类别&#xff1a;MCU 封装规格&#xff1a;64-LQFP&#xff08;10x1…

View事件分发

MotionEvent 1.简介 MotionEvent 是Android系统中一个非常重要的类&#xff0c;它代表了屏幕上发生的触摸事件。当用户在屏幕上触摸、滑动或者长按时&#xff0c;都会生成一个MotionEvent对象&#xff0c;这个对象包含了触摸动作的各种信息。 2.事件类型 ACTION_DOWN&#x…

沃尔玛百货有限公司 企业网页设计制作 企业html网页成品 跨国公司网页设计开发 web前端开发,html+css网页设计素材,静态html学生网页成品源码

沃尔玛百货有限公司 WalMart 7页面 企业主题 带jquery图片轮播特效 滚动文字 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.or…

接口自动化框架搭建(八):pytest+allure+jenkins接入

1&#xff0c;安装allure插件 2&#xff0c;创建jenkins项目 怎么确定路径&#xff0c;可以查看工作空间&#xff0c;jenkins默认根目录就是工作空间 配置执行用例的命令&#xff0c;可以现在pycharm上试一下&#xff0c;然后在jenkins中配置&#xff1a; 把启动java服务的代…

数据结构:基于数组实现栈

1 前言 栈是一种先进后出的线性表。向一个栈插入新元素可以叫做进栈、入栈、压栈&#xff0c;新元素必须放到栈顶元素上面&#xff0c;使之成为新的栈顶&#xff1b;从一个栈删除元素可以叫做出栈、退栈&#xff0c;它将栈顶元素删除&#xff0c;使和原来栈顶元素相邻的元素称…

Vue指令之v-for

跟其他语言中的for一样&#xff0c;是用来渲染多个类似实例的。 语法为v-for"(item, index) in 可迭代对象"&#xff0c;一般就用于遍历数组。这里的语法跟Python中的for循环enumerate也有点相似之处&#xff0c;但要注意item在前&#xff0c;index在后&#xff0c;…

【MATLAB源码-第21期】基于matlab的BCH码编码译码仿真,调制使用QPSK,对比编码与未编码的误码率曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 QPSK调制解调&#xff1a;QPSK&#xff08;Quadrature Phase Shift Keying&#xff09;调制解调**是一种数字调制技术&#xff0c;通常用于数字通信系统。 调制&#xff1a; 1. 首先&#xff0c;将数字信号分成两路&#xff…

【浅尝C++】使用模板实现泛型编程第二弹=>非类型模板参数/模板特化/模板分离编译详解

&#x1f3e0;专栏介绍&#xff1a;浅尝C专栏是用于记录C语法基础、STL及内存剖析等。 &#x1f3af;每日格言&#xff1a;每日努力一点点&#xff0c;技术变化看得见。 文章目录 非类型模板参数模板的特化概念函数模板特化类模板特化全特化偏特化 模板分离编译分离编译概念模板…