算法札记:利用floyd判环算法优化SPFA判负环算法

前置:

免责声明:我自己看了这个博客后突发奇想,如有雷同纯属巧合

Using the Shortest Path Faster Algorithm to find a negative cycle. | KonaeAkira's blog

优化过程:

我的优化思路跟这个博客基本一样,具体可跳转链接查看

但这个博客中他通过DFS来提前判环

众所周知,floyd判环算法(即龟兔赛跑算法)可以用来快速判环

那我把DFS换成floyd岂不更快 Σ(っ °Д °;)っ

思路总结:

++增添计时器+floyd判环++

代码:

cycle()是floyd判环,

cpp 复制代码
#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=2e3+5,M=1e4+5;
int n,m,d[N],h[N],e[M],ne[M],w[M],idx,cnt[N];
bool vis[N];
int pre[N];
void init(){
    idx=0;
    memset(h,-1,sizeof(h));
}
void add(int a,int b,int c){
    e[idx]=b;
    w[idx]=c;
    ne[idx]=h[a];
    h[a]=idx++;
}
bool cycle(int u){
    int slow=u,fast=pre[u];
    do{
        if (pre[slow]==-1 || pre[fast]==-1 || pre[pre[fast]]==-1){
            return false;
        }
        slow=pre[slow];
        fast=pre[pre[fast]];
    }while (slow!=fast);
    return true;
}
bool spfa(){
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    memset(d,0,sizeof(d));
    memset(pre,-1,sizeof(pre));
    int step=0;
    queue<int> q;
    for (int i=1;i<=n;i++){
        q.push(i);
        vis[i]=true;
    }
    while (!q.empty()){
        int now=q.front();
        q.pop();
        vis[now]=false;
        for (int i=h[now];i!=-1;i=ne[i]){
            int j=e[i];
            if (d[j]>d[now]+w[i]){
                pre[j]=now;
                d[j]=d[now]+w[i];
                cnt[j]=cnt[now]+1;
                if (cnt[j]>=n){
                    return true;
                }
                if (++step>=(n<<1)){
                    if (cycle(j)){
                        return true;
                    }
                    step=0;
                }
                if (!vis[j]){
                    q.push(j);
                    vis[j]=true;
                }
            }
        }
    }
    return false;
}

int main(){
    init();
    scanf("%d%d",&n,&m);
    for (int i=0,a,b,c;i<m;i++){
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    if (spfa()){
        puts("Yes");
    }else{
        puts("No");
    }
    return 0;
}

效果:

在Acwing上亲测比朴素SPFA快了50倍,比stack替换版快了1.2~1.4倍

相关推荐
罗湖老棍子8 小时前
【例 1】Sightseeing Trip(信息学奥赛一本通- P1494)(洛谷-P10927)
数据结构·算法·图论·最短路·floyd·最小环
stsdddd10 小时前
YOLO算法建筑工地安全帽目标检测数据集16881张:标注核对笔记
算法·yolo·目标检测
CV爱数码11 小时前
论文精读|Learned Primal-Dual:把原始–对偶算法展开成网络
图像处理·算法·计算机视觉·ct·重建·断层扫描
yuniko-n11 小时前
【算法】约瑟夫环问题
java·算法
l1t12 小时前
测试DuckDB v2.1.0-alpha49002的bignum乘法
数据库·sql·算法·duckdb
Nil20812 小时前
LeetCode 283移动零
数据结构·算法·leetcode
CQU_JIAKE12 小时前
10.18【A】
算法
LMT流氓兔12 小时前
第五单元——第4课:给工具参数加校验
java·前端·算法·ai·langchain
物联网软硬件开发-轨物科技13 小时前
【轨物方案】深度解读开关柜智能感知及一键顺控专家系统
大数据·运维·网络·人工智能·算法·机器人
行者全栈架构师14 小时前
我用 TRAE Work 把桌游之夜搬进了浏览器:一个计分器的从创意到上线
前端·算法·架构