与其说是 SPFA 算法的优化,倒不如说是 Bellman-Ford 算法的优化。

栈优化

将原本的 bfs 改为 dfs,在寻找负环时可能有着更高效的效率,但是最坏复杂度为指数级别。

void dfs_spfa(int u) {
if (fg) return;
vis[u] = true;
for(pil it : son[u]) {
int v = it.first;
ll w = it.second;
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;
}

SLF 优化

将一般的队列换成双端队列,判断与队首元素的 dis 的大小,小的就放队首,大的就放队尾。

void spfa(int s) {
for(int i = 1; i <= n; ++ i) {
dis[i] = inf;
}
dis[s] = 0;
q.push_back(s);
f[s] = 1;
while (!q.empty()) {
int u = q.front();
q.pop_front();
f[u] = 0;
for (pii it : son[u]) {
int v = it.first;
int w = it.second;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (! f[v]) {
if (! q.empty() && dis[v] < dis[q.front()]) {
q.push_front(v);
}
else q.push_back(v);
f[v] = 1;
}
}
}
}
}

D´Esopo-Pape 优化

将队列换成双端队列,判断一个点是否入过队列,没入过就放到队尾,如果就放到队首。

void spfa(int s) {
for(int i = 1; i <= n; ++ i) {
dis[i] = inf;
}
dis[s] = 0;
q.push_back(s);
f[s] = 1;
vis[s] = 1; // 是否入过队
while (!q.empty()) {
int u = q.front();
q.pop_front();
f[u] = 0;
for (pii it : son[u]) {
int v = it.first;
int w = it.second;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (! f[v]) {
if (vis[v]) {
q.push_front(v);
}
else {
q.push_back(v);
vis[v] = 1;
}
f[v] = 1;
}
}
}
}
}

LLL 优化

将普通队列换成双端队列,每次将入队结点距离和队内距离平均值比较,如果更大则插入至队尾,否则插入队首。

void spfa() {
ll sum = 0;
for (int i = 1; i <= n; ++ i) {
dis[i] = inf;
}
dis[s] = 0;
q.push_back(s);
g[s] = 1;
sum += dis[s];
while (!q.empty()) {
int u = q.front();
q.pop_front();
vis[u] = false;
sum -= dis[s];
for (pli it : son[u]) {
if (dis[it.second] > dis[u] + it.first) {
dis[it.second] = dis[u] + it.first;
if (! vis[it.second]) {
if (q.empty() || dis[it.second] > sum / ((int)q.size())) {
q.push_back(it.second);
}
else {
q.push_front(it.second);
g[it.second] = 1;
}
vis[it.second] = true;
}
}
}
}
}

「学习笔记」SPFA 算法的优化的更多相关文章

  1. 「学习笔记」FFT 之优化——NTT

    目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...

  2. 「学习笔记」字符串基础:Hash,KMP与Trie

    「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...

  3. 「学习笔记」Min25筛

    「学习笔记」Min25筛 前言 周指导今天模拟赛五分钟秒第一题,十分钟说第二题是 \(\text{Min25}​\) 筛板子题,要不是第三题出题人数据范围给错了,周指导十五分钟就 \(\text{AK ...

  4. 「学习笔记」FFT 快速傅里叶变换

    目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...

  5. 「学习笔记」Treap

    「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...

  6. 「学习笔记」平衡树基础:Splay 和 Treap

    「学习笔记」平衡树基础:Splay 和 Treap 点击查看目录 目录 「学习笔记」平衡树基础:Splay 和 Treap 知识点 平衡树概述 Splay 旋转操作 Splay 操作 插入 \(x\) ...

  7. 「学习笔记」wqs二分/dp凸优化

    [学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...

  8. 「学习笔记」斜率优化dp

    目录 算法 例题 任务安排 题意 思路 代码 [SDOI2012]任务安排 题意 思路 代码 任务安排 再改 题意 思路 练习题 [HNOI2008]玩具装箱 思路 代码 [APIO2010]特别行动 ...

  9. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  10. 「学习笔记」递推 & 递归

    引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...

随机推荐

  1. SQL的分类

    DDL: 数据定义语言,用来定义数据库对象(数据表,表 ,字段) : DML:数据操作语言,用来对数据库表中的数据进行增删改 : DQL:数据库查询语言,用来查询数据库中的表的记录 DCL:数据控制语 ...

  2. Java开发词汇

    Java基础常见英语词汇(70个) OO: object-oriented ,面向对象 OOP: object-oriented programming,面向对象编程 JDK:Java develop ...

  3. TensorFlow 的 Graph 模式转换

    定义 TensorFlow 图形并将其保存到磁盘上. 使用 TensorFlow 的 tf.Graph() 和 tf.Session() 函数来定义和运行 TensorFlow 图形,并使用 tf.t ...

  4. MQ(创建MQ注意事项)

    创建MQ队列管理器时,需要注意的事项包括以下几点: 1) 队列管理器的日志类型以及日志文件的大小和个数,要根据用户数据量的大小.各个队列上的消息总容量,来计算日志的总容量,以免在系统运行过程中出现日志 ...

  5. Windows11右键改Win10

    Win11改Win10右键模式 1.以管理员身份运行CMD控制台 2.在控制台中输入下列代码后回车执行 reg add "HKCU\Software\Classes\CLSID\{86ca1 ...

  6. Fastboot_Cmd

    /* -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- */adb命令:/* -*-* ...

  7. Linux & 标准C语言学习 <DAY9_1>

        2.函数传参:         1.函数中定义的变量属于该函数,出了该函数就不能再被别的函数直接使用         2.实参与形参之间是以赋值的方式进行传递数据的,并且是单项值传递     ...

  8. Git 操作命令清单 入门到精通(保姆级)

    一般来说,日常使用只要记住下图6个命令,就可以了.但是如果你想熟练使用它,要记住大概80个命令. 下面是常用的 Git 命令.几个专用名词的译名如下: Workspace:工作区 Index / St ...

  9. 音质效果不错的Pcie声卡之CM8828听歌声卡

    CM8828芯片是cmedia骅讯公司生产的,采用这个芯片的声卡价格不一,便宜的100多,贵一点的500多.价位在100多买到这款声卡还是比较实惠的,再高一点的声卡都是堆料的.CM8828声卡是原生的 ...

  10. 聊天小精灵ChatGPT,好与不好大揭秘!

    一.引言 在一个遥远的地球上,有一个名为ChatGPT的魔法盒子,它能够用智慧回答你的问题,解决你的困扰.它是一个聪明的家伙,但和任何家伙一样,有优点也有缺点.现在就让我们一起来探索这个神秘的魔法盒子 ...