spfa算法(c++)
SPFA算法(对bellman - ford的优化)(适用于负权边且不能有负权回路)
一般情况下spfa算法也可以解决正权边问题,且时间比Dijkstrsa更快(但是如果出题人卡掉了spfa算法,就只能用Dijkstrsa算法了)
上一篇博客介绍了bellman_ford算法,建议两个算法一起看
区别:bellman_ford算法更新每一个点,而spfa算法只更新变小的点。
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1e5 + 10;
int n,m;
int h[N] , e[N] , w[N] , ne[N] , idx;
int dist[N];
bool st[N];void add(int a , int b , int c)
{e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx ++;
}void spfa()
{queue<int>q;//存储每次更新的所有的点dist[1] = 0;q.push(1);st[1] = true;while(!q.empty()){int t = q.front();//每次从队列取出一个来更新所有它能够到达的点q.pop();st[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(!st[j])//如果队列里面没有这个点就入队{q.push(j);st[j] = true;}}}}}int main()
{cin>>n>>m;memset(dist,0x3f,sizeof dist);memset(h,-1,sizeof h);for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;add(a,b,c);}spfa();if(dist[n] == 0x3f3f3f3f) cout<<"impossible";else cout<<dist[n];return 0;
}
除此之外,spfa算法还可以用来判断是否存在负环。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n,m;//n是点数,m是边数
int h[N] , e[N] , w[N] , ne[N] , idx;
int dist[N],cnt[N];
bool st[N];void add(int a,int b, int c)
{e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx ++;
}bool spfa()
{queue<int>q;//这里不需要求最短路,所以不需要更新初始值。for(int i=1;i<=n;i++)//有可能从一号点到达不了负环,所以先将每个点都入队。{q.push(i);st[i] = true;}while(!q.empty()){int t = q.front();q.pop();st[t] = false;for(int i = h[t] ; i != -1 ; i = ne[i]){int j = e[i];if(cnt[j] >= n) return true;//如果有点入队的次数大于等于n,说明存在负权回路if(dist[j] > dist[t] + w[i]){dist[j] = dist[t] + w[i];if(!st[j]){q.push(j);cnt[j] ++;//入队一次就将这个点入对的次数加一st[j] = true;}}}}return false;
}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);}if(spfa()) cout<<"Yes";else cout<<"No";return 0;
}
总结spfa
- 初始化第一个点
- 更新每个点的节点
spfa算法(c++)相关推荐
- poj 3662 Telephone Lines spfa算法灵活运用
意甲冠军: 到n节点无向图,它要求从一个线1至n路径.你可以让他们在k无条,的最大值.如今要求花费的最小值. 思路: 这道题能够首先想到二分枚举路径上的最大值,我认为用spfa更简洁一些.spfa的本 ...
- 图论-最短路径--3、SPFA算法O(kE)
SPFA算法O(kE) 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束. 这个算 ...
- HDU3440(差分约束+SPFA算法)
题意:两栋房子之间的最大距离为D,也就是A-B<=D,现在求出最矮和最高房子之间的最大距离 思路:差分约束+SPFA算法: 当问题可以转化为形如一组 xi‑x'i<=yi 或一组 xi‑x ...
- poj2387(SPFA算法)
1.建⽴⼀个队列,初始时队列⾥只有起始点,再建⽴⼀个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极⼤值,该点到他本⾝的路径赋为 无穷大).然后执⾏松弛操作,⽤队列⾥有的点作为起始点去刷新到所 ...
- 图论刷水题记录(二)(最短路-----SPFA算法)
继第一篇的后续,又来刷水题了,写的是SPFA算法,这个算法的复杂度比较玄学,感觉能不用就不用了,但是他的好处就是可以判断负圈. 3月26日: 1.POJ 1847 Tram 题意:在一个交通网络上有N ...
- SPFA算法O(kE)
SPFA算法O(kE) Dijkstra和Floyed是不断的试点.Dijkstra试最优点,Floyed试所有点. Bellman-Ford和SPFA是不断的试边.Bellman-Ford是盲目的试 ...
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法
一.floyd 1.介绍 floyd算法只有五行代码,代码简单,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3),可以求多源最短路问题. 2.思想: Floyd算法的基本思想如下:从任意 ...
- 最短路径:Dijkstra、BellmanFord以及SPFA算法
最短路径问题 1.Dijkstra算法 简介 (1)Dijkstra算法伪代码 (2)C++ 邻接表版代码 (3)优化 (4)题型分析 2.Bellman Ford算法 简介 (1)Bellman算法 ...
- 最短路径(Dijkstra、Bellman-Ford和SPFA算法)
最短路径(Dijkstra.Bellman-Ford和SPFA算法) 前言 图的存储方式 邻接矩阵 邻接表 链表建立 利用vector 结构体 核心思路 Dijkstra算法 图解 基本思想 求解步骤 ...
- HDU SPFA算法 Invitation Cards
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535 分析: 题意:求1点到其它点的最短距离之和+其它点到1点的最短距离之和 前面一部分直接用SPFA ...
最新文章
- thinkphp链接mssql以及查询中文乱码问题
- 【Android 安装包优化】动态库打包配置 ( “armeabi-v7a“, “arm64-v8a“, “x86“, “x86_64“ APK 打包 CPU 指令集配置 | NDK 完整配置参考 )
- 【转】jmeter响应结果乱码问题
- ibatis学习笔记
- 判断unsigned long long乘法溢出_信息安全课程17:缓冲区溢出2
- java字符集编码是,java字符集与编码有关问题
- 移动端阻止body左右偏移
- Leetcode--322. 零钱兑换
- 一些java,spring boot图解
- python docx 替换文字_在.docx文件-Python中查找和替换文本
- mysql 字符串搜_Mysql搜索字符串
- libxml主要函数说明 (二)
- 3dmax渲染器下载VRay4.1渲染器下载安装教程(支持3dmax2013-2019)
- Windows10超级管理员账号权限受限的问题
- 好用的web报表设计器(报表工具)
- 对接中国银联刷卡支付系统架构小demo
- 日月年时分秒转换为年月日时分秒
- 一键定时关机及取消关机
- 移动和包不能激活NFC问题
- PMP章节练习(第六章:项目进度管理)
热门文章
- 昆仑通态复制的程序可以用吗_第478期丨相同功能带定时器的PLC程序怎么简化?非标设备出口到日本,应该怎么配电。...
- 方舟开服务器游戏基础管理设置
- 禁用计算机端口,电脑如何关闭445端口
- 西安电子科技大学出版社 线性代数 参考答案 刘三阳
- 阿里图标库——批量下载图标
- Markdown 数学符号大全
- 多所985、211高校教授被通报!国自然发布处理决定!
- 计算机基础知识教程函数,EXCEL函数教程_电脑基础知识_IT计算机_专业资料.ppt
- 计算机指纹驱动程序,解决方法:联想笔记本指纹识别驱动程序安装教程[详细]...
- 驱动外挂的原理及检测手段(自瞄篇)