有向图缩环/求强连通分量

来源:互联网 发布:ip反查域名 编辑:程序博客网 时间:2024/06/06 03:34

例题

这里写图片描述
直接考虑spfa的话要存状态(每个点只能拿一次),这样压根没办法

显然走到一个环里就可以把这个环全部拿掉,这样的话我们将有向图变为有向无环图,就可以spfa了。
那么问题来了,怎么缩环。

Tarjan缩环

时间O(n)

我们知道,对于一个有向图的dfs树,有两种特殊的边:
这里写图片描述
绿色的为返祖边,即所返回的边是当前点的祖先;
红色的为横叉边,即返回的不是当前点的祖先。
显然只有返祖边会产生环,那么我们每一次找到这种返祖边,就把这个环里的缩成一个点。

利于实现的细节
0) 先标记是属于哪个环的,之后再统一操作
1) 我们应该将X下面的所有环缩完,再求X为环顶的环 即为我们应该开一个栈储存可能在环中的点
2) 将环中的所有点的边 集中 可以用边集数组指针指指指来做

Kosaraju

时间同样为O(n),但常数比Tarjan大.

首先我们在图G的逆向图中进行一次dfs求出后序序列(出点时标号).
然后在原图中按照所求序列,逆序对未被dfs到的点进行dfs遍历,每一次得到的一棵DFS树就是一个强连通分量. 即需要dfs2次.

证明

记在第二次DFS中, 当前树根为R,当前遍历到的点为C

求证: R与C互达

已知C的后序编号肯定比R的要小,且在原图中,存在路径(R,C),就意味着在逆向图中存在路径(C,R)
现在需要证明的就是,在原图中存在路径(C,R),即在逆向图中存在路径(R,C).

因为R编号比C要大,那么假如在逆向图中不存在路径(R,C)
但因为已知逆向图中存在路径(C,R),那么R的编号必然比C要小1.这与已知矛盾.

所以逆向图中必然存在路径(R,C),即原图中存在路径(C,R).

即R与C是互达的.对于每一个C都可以这样考虑,然后根据传递性得出,这是一个强连通分量.

第二个方面: 会不会有点存在于该强连通分量,而没有被第二次DFS到呢?
因为强连通,所以必然会DFS到.

参考

http://blog.sina.com.cn/s/blog_4dff87120100r58c.html


  1. 3种情况考虑: 当存在路径(C,R)时,
    1) 若不经过C到了R,那么R显然会比C早退出.
    2) 若经过C到了R,显然R也会比C早退出.
    3) 若在逆向图中存在先到R,且在R没退出的情况下到了C,与已知不矛盾,且说明了在逆向图中存在路径(R,C). ↩
0 0
原创粉丝点击