NeFut Logo NeFut
EN 管理员登录

解密 DFS-SPFA:负环判断的双刃剑

发布于:2026-06-05 13:55 最后更新:2026-06-06 13:04
#algorithm #optimization #Graph

判负环,一直流传着一个“黑魔法”:DFS 版 SPFA。据说它判断负环的速度比 BFS 版快上百倍。于是,很多选手将其奉为圭臬,直到某天他们在赛场上遇到了精心构造的“卡图”,眼睁睁看着 $O(VE)$ 的复杂度退化成了指数级


为什么它快?

DFS 版 SPFA 的核心逻辑是:沿着当前的路径一路向下搜,如果搜到了正在栈中的节点,则立即判定存在负环。

// 核心逻辑片段
bool dfs_spfa(int u) {
    instack[u] = true;
    for (auto edge : adj[u]) {
        if (dist[edge.v] > dist[u] + edge.w) {
            dist[edge.v] = dist[u] + edge.w;
            if (instack[edge.v] || dfs_spfa(edge.v)) return true;
        }
    }
    instack[u] = false;
    return false;
}

为什么它危险?

成也回溯,败也回溯。DFS 的本质是优先走深。如果图中没有负环,但存在权值级差显著的多层负权路径,DFS 就会陷入一种极其恐怖的状态:

每当它通过一条负权边发现了一条更短的“捷径”,它就会无情地推翻之前已经遍历过的所有后继节点,并强迫它们重新进入递归栈。

“普通级差只会带来常数级的冗余,但‘成倍数递减的级差结构’会将 DFS 变成一个物理意义上的二进制计数器。二进制计数器的逻辑,在算法时间复杂度上直接对应 $O(2^n)$ 指数级爆炸。

层级菱形图 (Diamond Chain)

要构造 $n$ 层结构,每层包含两个节点。


金句提炼:
“在算法竞赛中,稳定比爆发更重要。DFS-SPFA 就像是带毒的禁药,它能让你跑得飞快,也能让你在终点线前‘爆体而亡’。”

原文链接: local://DFS-SPFA

[h] 返回首页