算法札记:SPFA判负环算法的证明

SPFA判负环算法有两种主流判定方式,核心都基于图论的++抽屉原理++完成严谨证明:

++前言:SPFA基于++ bellman-foyd ++,想不通就用bellman-foyd来想想++

一、基于点入队次数的判定证明

  1. ‌判定规则‌:若图中某节点的入队次数≥总节点数n,则图中存在负环。
  2. ‌证明逻辑 ‌:
    每次节点入队都对应一次最短路径的松弛更新,且更新后该点对应的最短路边数严格递增。当某点入队n次时,说明它对应的最短路径边数≥n,路径上的节点总数至少为n+1。根据抽屉原理,n个节点的图中,路径必然存在重复出现的顶点,也就是形成了环路。而SPFA仅在路径总权值变小时才会触发松弛更新,因此这个环路的总边权之和必然为负数,即存在负环。

二、基于最短路边数的判定证明

  1. ‌判定规则‌:维护cnt数组记录从起点到当前节点的最短路径经过的边数,若某点的cnt值≥n,则图中存在负环。
  2. ‌证明逻辑 ‌:
    若某点的最短路径包含≥n条边,路径上的节点数至少为n+1,再次通过抽屉原理可推导出路径中必然存在重复顶点,也就是形成了环路。结合SPFA的松弛更新规则,只有路径总权值减小才会更新距离,因此该环路的边权和为负,直接判定存在负环。这种方式比统计入队次数效率更高,是工程中更常用的实现方案。

补充说明

为了能检测到图中任意位置的负环,算法初始化时会将所有节点直接加入队列,等价于在原图中新增一个虚拟源点,向所有节点连一条权值为0的边,保证原图中所有负环都能被虚拟源点可达,不会出现漏判的情况。

相关推荐
I_belong_to_jesus4 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Code_Solitude11 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司11 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP14 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀14 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落15 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi16 小时前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
꧁细听勿语情꧂17 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
俊俊几年的17 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c