• 图上负环判定小记


    本文全文参考了 《算法竞赛进阶指南》by lydrainbowcat

    如果一个环上所有边的权值和为负数,称其为负环。

    常用的能够判断负环的算法一般就是 Bellman-Ford 系的最短路算法。

    若图中存在负环,那么直观表现为:总是存在一条边 ((x,y)), 使得 (sf d[y]le d[x]+w(x,y)) 不被满足。根据抽屉原理, 若源点到节点 (x) 的最短路包含 (ge n) 条边, 那么这条路径必然重复经过了某个点 (p), 如果这个环是正环, 显然去掉这个环后会得到一条更短的最短路, 与假设矛盾, 于是这个环必定是负环, 由负环的性质知从源点到节点 x 不存在最短路。


    Bellman-Ford 算法判定负环

    若经过 n 次迭代后, 算法未结束, 则图中存在负环, 反之不存在。

    示例代码, 参考了 OI-wiki:

    bool Bellman_Ford() {
    	for(int i=0; i<n; ++i) {
    		bool jud = false;
    		for(int j=1; j<=n; ++j)
    			for(int k=h[j]; ~k; k=nxt[k])
    				if(dist[p[k]] > dist[j] + w[k])
    					dist[p[k]] = dist[p[k]] + w[k],
    							jud = true;
    		if(!jud) break;
    	}
    	for(int j=1; j<=n; ++j)
    		for(int k=h[j]; ~k; k=nxt[k])
    			if(dist[p[k]] > dist[j] + w[k])
    				return true;
    	return false;	
    }
    

    队列优化的 Bellman-Ford 判负环:

    (cnt[x]) 表示从源点到 (x) 的最短路经过的边数, 在最短路执行的过程中维护其, 不难发现可以轻松地判断某一时刻是否有某个 (x) 满足 (cnt[x]ge n), 就可以判负环了。

    另一种方法是记录每个点入队的次数,次数达到 n 的时候说明有负环。(我还不懂这个)

  • 相关阅读:
    《分布式系统关注点——数据一致性(上篇)》阅读笔记
    2.23寒假学习记录
    2.22寒假学习记录
    2.21寒假学习记录
    2.20寒假学习记录
    2.19寒假学习记录
    2.18寒假学习记录
    2.17寒假学习记录
    2.17周一毕设改进计划
    2.16寒假学习记录
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14056374.html
Copyright © 2020-2023  润新知