SPFA可能会被卡掉,能用dijkstra就别用SPFA,代码较长,但我已尽力做到解释,请耐心看下去,存储为邻接表存储。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f//(宏定义一个很大的值,例如0x3f3f3f3f等)
using namespace std;
int n,m,cnt;//cnt 计数器(有cnt条边)
struct edge//结构体定义
{
int v,w,nxt;//v 目标点 w 边权 nxt 这条边的上一条边(遍历)
};
edge e[3000010];//存边(边表)
int dis[3001000];//记录起点到第x个点的距离
int h[1001000];//记录第x个点所发出的最后一条边
bool f[1001000];//判断是否在队列内
deque<int> q;//双端队列
void add(int,int,int);
void spfa()//SLF优化
{
for(int i=1;i<=n;++i)
{
dis[i]=inf;
}//初始化,也可以用memset()
dis[1]=0;//起点到自己的距离为0 (该题起点为1)
q.push_back(1);//起点入队
f[1]=1;//标志起点已入队
while(!q.empty())
{
int top=q.front();//取队首元素
q.pop_front();//踢出队列
int w=dis[top];//w 起点的值
f[top]=0;//代表该元素已出队
for(int i=h[top];i;i=e[i].nxt)//邻接表遍历每一条边
{
int v=e[i].v;//目标点
int di=e[i].w;//边权
if(dis[v]>w+di)//松弛操作
{
dis[v]=w+di;//更新起点到点v的值
if(!f[v])//判断是否入队,没入队便入队
{
if(!q.empty()&&dis[v]<dis[q.front()])//如果比队首元素小,从队首入队
{//这里一定要把!q.empty()放在前面,编译时它会从前往后读,如果把它放后面而队列又为空,dis[v]<dis[q.front()]调用时会RE
q.push_front(v);//入队操作
}
else q.push_back(v);//否则从队尾入队
f[v]=1;//标志已入队
}
}
}
}
}
int main()
{
memset(h,0,sizeof h);//数组初始化
memset(f,false,sizeof f);//数组初始化
scanf("%d%d",&n,&m);
for(int a,b,c,i=1;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c); //加边
add(b,a,c);//加边,如果是有向图,删掉这一步操作
}
spfa();//调用函数
printf("%d",dis[n]);//输出,根据题目要求,这里是输出1到n的最短距离
return 0;
}
void add(int u,int v,int w)
{
e[++cnt].v=v;//cnt 边的编号
e[cnt].w=w;
e[cnt].nxt=h[u];//指向上一条边
h[u]=cnt;//更新最后一条边
}

2022.7.8更新:

新增判断负环的写法和dfs写法

dfs写法判断负环更快,但求答案很慢

bfs队列写法求答案快,但判断负环很慢

根据题目情况来

bfs队列写法:

bool spfa()
{
for(rint i=1;i<=n;++i)
dis[i]=0x7ffffff;
dis[0]=0;
q.push_back(0);
vis[0]=true;
++in[0];//差记录入队次数
while(!q.empty())
{
int u=q.front();
q.pop_front();
vis[u]=false;
for(rint i=h[u];i;i=e[i].nxt)
{
int v=e[i].v;ll w=e[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
++in[v];
if(in[v]>=n+1) return false;//判断负环
if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);
else q.push_back(v);
vis[v]=true;
}
}
}
}
return true;
}

dfs写法:

void dfs_spfa(int u)
{
if(fg) return;
vis[u]=true;
for(rint i=h[u];i;i=e[i].nxt)
{
int v=e[i].v;
ll w=e[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(vis[v]==true)//如果这个点被访问过,就说明这是负环
{
fg=true;//打标记
return;
}
else dfs_spfa(v);
}
}
vis[u]=false;
}

SPFA算法(SLF优化)2022.7.8更新的更多相关文章

  1. 关于SPFA算法的优化方式

    关于SPFA算法的优化方式 这篇随笔讲解信息学奥林匹克竞赛中图论部分的求最短路算法SPFA的两种优化方式.学习这两种优化算法需要有SPFA朴素算法的学习经验.在本随笔中SPFA朴素算法的相关知识将不予 ...

  2. spfa的SLF优化

    spfa的SLF优化就是small label first 优化,当加入一个新点v的时候如果此时的dis[v]比队首dis[q.front()]还要小的话,就把v点加入到队首,否则把他加入到队尾,因为 ...

  3. HDU4725(KB4-P SPFA+LLL+SLF优化)

    The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. 并不对劲的图论专题(三):SPFA算法的优化

    1.bzoj1489-> 这是个新套路. 我们希望找到最小的x,那么可以二分x,然后判断是否存在圈的边权的平均值小于等于x. 设圈的边权依次为w1,w2,w3,…,wk,平均值为p, 则有p= ...

  5. 《SPFA算法的优化及应用》——姜碧野(学习笔记)

    一.核心性质:三角不等式.最短路满足d[v]<=d[u]+w(u,v) 二.SPFA两种实现: 常见的是基于bfs的,这是直接对bellman-ford用队列维护.根据最短路的长度最长为(n-1 ...

  6. 蓝书3.3 SPFA算法的优化

    T1 最小圈 bzoj 1486 题目大意: 一个环的权值平均值为定义为一个这个环上所有边的权值和除以边数 求最小的环的权值平均值 思路: 二分一个值 把所有边减去这个值 判断是否有负环 #inclu ...

  7. 队列优化dijsktra(SPFA)的玄学优化

    转载:大佬博客 最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下 前置知识:spfa(不带任何优化) 由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2​ 优化 对一些数 ...

  8. SPFA算法的SLF优化 ——loj#10081. 「一本通 3.2 练习 7」道路和航线

    今天做到一道最短路的题,原题https://loj.ac/problem/10081 题目大意为给一张有n个顶点的图,点与点之间有m1条道路,m2条航线,道路是双向的,且权值非负,而航线是单向的,权值 ...

  9. SPFA求最短路——Bellman-Ford算法的优化

    SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE), ...

随机推荐

  1. JS&JQ

    1.css()设置单个或多个值: $(".iconList a").css("width", "32%")--单值:属性和值逗号分隔. $( ...

  2. .Net 在容器中操作宿主机

    方案描述 在 docker 容器中想操作宿主机,一般会使用 ssh 的方式,然后 .Net 通过执行远程 ssh 指令来操作宿主机.本文将使用 交互式 .Net 容器版 中提供的镜像演示 .Net 在 ...

  3. 【多线程】线程优先级 Priority

    线程优先级 Priority Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度 器按照优先级决定应该调度哪个线程来执行. 线程的优先级用数字表示,范围从1~10. Thre ...

  4. MySQL之事务和redo日志

    事务 事务的四个ACID特性. Atomicity 原子性 Consistency 一致性 Isolation 隔离性 Durability 持久性 原子性 原子性即这个事务的任务要么全做了,要么全部 ...

  5. 《HALCON数字图像处理》第六章笔记

    目录 第六章 图像增强 图像增强的概念和分类 灰度变换 直方图处理 图像的平滑 图像的锐化 图像的彩色增强 我在Gitee上建了个仓库,会将学习书本的时候打的一些代码上传上去,笔记中所有代码都在仓库里 ...

  6. 一文澄清网上对 ConcurrentHashMap 的一个流传甚广的误解!

    大家好,我是坤哥 上周我在极客时间某个课程看到某个讲师在讨论 ConcurrentHashMap(以下简称 CHM)是强一致性还是弱一致性时,提到这么一段话 这个解释网上也是流传甚广,那么到底对不对呢 ...

  7. QQ空间未授权评论_已忽略

    看群友们聊天时发现的, 大概是做了查看了动态访问时间的一个设置, 但是仅自己可见的说说还是被评论了的这么一个问题. 闲的没事就翻了一下找一下问题. 这个方法嘎嘎鸡肋, 可以说完全没用, 交到tsrc, ...

  8. 腾讯QQ快捷登陆

    腾讯QQ快捷 相关各语言对接qq快捷登录教程 [C#]QQ开放平台(QQ站外登录)_流程和源码示例 j2ee中实现QQ第三方登陆 web实现QQ第三方登录 asp.net网站接入QQ登录 php实现q ...

  9. Django-使用nginx部署

    本地部署 uWSGI 在部署之前,我们得先了解几个概念 wsgi web应用程序之间的接口.它的作用就像是桥梁,连接在web服务器和web应用框架之间. uwsgi 是一种传输协议,用于定义传输信息的 ...

  10. UiPath视频教程

    UiPath机器人企业框架简介https://www.bilibili.com/video/BV1SK411L7u9 UiPath借助第三方Pdf软件工作https://www.bilibili.co ...