SPFA判负环

有不足的地方请指出

本蒟蒻一定会修改吼

【前言】

最短路的求法中最广为人知的我仅仅知道的,有弗洛伊德,dijkstra和SPFA。

弗洛伊德最简单的三重循环,复杂度n^3,一般也就做个n小的题目,遇到n大一点的(超过1000)几乎就只能拿部分分。

SPFA是一种广为人知的已经死掉的算法(某人说过一道图论题如果不卡卡SPFA就不是一道好的图论题目),但是他却有一个很重要的作用,是其他三者无法代替的,那就是这篇博客的题目,判负环!

dijkstra是这三种里面最为稳定的一种算法,何为稳定,弗洛伊德只能跑那么小的数据范围就可以看出来,在很多题目上面只能打一下暴力,SPFA就更不用多说了他死了,所以dijkstra理所当然的成为了最稳定的算法。

说这么多就是为了引出SPFA判负环!

【不可代替性】

dijkstra和弗洛伊德都是判断不了负环的

弗洛伊德可以判断负环

但是我不会

我也不想会

人家SPFA好不容易有一个活着的理由干嘛要给人家扼杀掉

dijkstra遇到负权边就死了

更别说负环了

但是SPFA可以判断负环

具体原因不多赘述了,学过dijkstra和弗洛伊德的应该都知道

但是我不知道

【具体实现】

SPFA的过程

每次都拿一个点到起点的距离来松弛其他的点到起点的距离

判负环

负环是一个边权值和等于负数的环

可以想想一下

如果SPFA遇到了负环会出现什么情况

一直松弛下去

因为每次出现的负数都可以让目前最短的边变得更短

所以可以根据这一点

开一个数组用来记录这是这一条链上第几个入队的数

然后每次松弛的时候都把到达的点入队的数标为前面这个点入队的次数+1,因为这是一个顺序的过程

就像是1,2,3……这样的数列

然后如果出现了负环就会和上面说的一样一直松弛下去

然后这个负环上的点入队的数就会不断变大

可以想一下

如果n个数连成一个点

那入队数最大才只能是n

所以只要某个点的入队数大于了n

那就可以证明他在不停得松弛

也就是出现了负环

【核心代码】

bool SPFA(int acioi)
{
queue<int>q;
for(register int i = 1;i <= n;++ i)
d[i] = 99999999;
d[acioi] = 0;
q.push(acioi);
while(!q.empty())
{
int x = q.front();
q.pop();use[x] = false;
for(register int i = head[x];i != 0;i = a[i].ne)
{
int y = a[i].y;
if(d[y] > d[x] + a[i].z)
{
d[y] = d[x] + a[i].z;
cnt[y] = cnt[x] + 1;
if(cnt[y] > n)
return false;
if(use[y] == false)
{
use[y] = true;
q.push(y);
}
}
}
}
return true;
}

【例题】

洛谷P2136 拉近距离

SPFA判负环板子题

详情解释请看

这里

洛谷P3385 【模板】负环

同样也是板子题

想请解释请看

这里

浅谈SPFA判负环的更多相关文章

  1. POJ 3259 Wormholes(SPFA判负环)

    题目链接:http://poj.org/problem?id=3259 题目大意是给你n个点,m条双向边,w条负权单向边.问你是否有负环(虫洞). 这个就是spfa判负环的模版题,中间的cnt数组就是 ...

  2. Poj 3259 Wormholes(spfa判负环)

    Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 42366 Accepted: 15560 传送门 Descr ...

  3. spfa判负环

    bfs版spfa void spfa(){ queue<int> q; ;i<=n;i++) dis[i]=inf; q.push();dis[]=;vis[]=; while(!q ...

  4. poj 1364 King(线性差分约束+超级源点+spfa判负环)

    King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14791   Accepted: 5226 Description ...

  5. 2018.09.24 bzoj1486: [HNOI2009]最小圈(01分数规划+spfa判负环)

    传送门 答案只保留了6位小数WA了两次233. 这就是一个简单的01分数规划. 直接二分答案,根据图中有没有负环存在进行调整. 注意二分边界. 另外dfs版spfa判负环真心快很多. 代码: #inc ...

  6. BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划

    BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ...

  7. [P1768]天路(分数规划+SPFA判负环)

    题目描述 “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了. 和C_SUNSHINE大神商量后,这道猥琐的题目终于出现在本次试题上了 ...

  8. LightOj 1221 - Travel Company(spfa判负环)

    1221 - Travel Company PDF (English) Statistics problem=1221" style="color:rgb(79,107,114)& ...

  9. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

随机推荐

  1. [BZOJ2157]旅游(树链剖分/LCT)

    树剖裸题,当然LCT也可以. 树剖: #include<cstdio> #include<algorithm> #define ls (x<<1) #define ...

  2. 函数式接口java.util.function

    什么是函数式接口 为什么要用函数式接口 java.util.function和其他的函数式接口 lamdba表达式 方法引用 流 Stream 1 什么是函数式接口 用@FunctionInterfa ...

  3. kube-state-metrics 详解

    原文:https://mp.weixin.qq.com/s/176eyFBknzdA5wpiJrxDSg 概述 已经有了 cadvisor.heapster.metric-server,几乎容器运行的 ...

  4. P1018 乘积最大(DP)

    题目 P1018 乘积最大 解析 区间DP 设\(f[i][j]\)表示选\(i\)个数,插入\(j\)个乘号时的最大值 设\(num[i][j]\)是\(s[i,j]\)里的数字 转移方程就是\(f ...

  5. [HNOI2012]矿场搭建 (点双连通)

    题目 [HNOI2012]矿场搭建 解析 这个题做的我十分自闭.. 没看出这个是个点双,然后一晚上+半上午.. 一看肯定和割点有关,我们找到所有的点双,会发现有这么几种情况 连通块中一个割点也没有,这 ...

  6. Django使用 django-allauth实现第三方登陆

    Django使用 django-allauth实现第三方登陆 这里我们使用 django-allauth 模块来实现第三方账号验证登录,官方文档如下:https://django-allauth.re ...

  7. 英语foteball足球历史

    foteball n.足球 现代足球 参见:现代足球 现代足球起源地是在英格兰.传说在11世纪,英格兰与丹麦之间有过一场战争,战争结束后,英格兰人在清理战争废墟时发现一个丹麦入侵者的头骨,出于愤恨,他 ...

  8. Xcode 10 Archive 时电脑卡死

    Xcode 10 Archive Unity5.x 导出工程时电脑卡死.解决办法:Targets - Build Settings - Debug Information Format 设置成DWAR ...

  9. 【BBED】编译及基本命令(1)

    [BBED]编译及基本命令(1) 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你 ...

  10. Altium Designer常用快捷键总结

    一.PCB中常用快捷键 ● R+L 输出PCB中所有网络的布线长度 ● Ctrl+左键点击 对正在布的线完成自动布线连接 ● M+G 可更改铜的形状; ● 按P+T在布线状态下,按Shift+A可直接 ...