bellman-ford判断负环
前置芝士:bellman-ford
板子:https://www.luogu.com.cn/problem/P3385
大家应该都会SPFA判负环了,但代码量实在是大的惊人。
那有没有相对方便的做法呢?有,SPFA的祖宗的原版bellmanford
那有同学就要问了:
bellman-ford稳定relax $n-1$次,怎么计一条边的relax次数呢?
A:把所有边再relax一遍,如果relax成功就有负环
核心代码:
for(int i = 1;i < n;++i)
for(int j = 1;j <= cnt;++j)
if(dis[edge[j].v] > dis[edge[j].u] + edge[j].w)
dis[edge[j].v] = dis[edge[j].u] + edge[j].w;
for(int i = 1;i <= cnt;++i)
if(dis[edge[i].u] > inf || dis[edge[i].v] > inf) continue; //源点到不了,有负环也没用
else if(dis[edge[i].v] > dis[edge[i].u] + edge[i].w) {cout << "YES" << endl;f = 1;break;}
if(!f) cout << "NO" << endl;
即 bellman-ford 板子 + m次relax,总复杂度$O(m(n-1)+m)=O(nm)$