数据结构-图的分析

来源:互联网 发布:mac过滤是什么意思 编辑:程序博客网 时间:2024/04/28 02:10

1、有向图的强连通分量的计算:Kosaraju算法

时间复杂度:O(V+E),对于有向图的强连通性查询可以在常数时间内完成。

步骤:1、对图G进行转置(反向图)得到图Gr

   2、对Gr求得逆反序,即Gr的拓扑序列

   3、从Gr的拓扑序列开始,进行深度优先搜索,得到的搜索树即强联通分量。

说实话,这个算法从代码量上是非常简洁的,仅仅就是从遍历所有节点(0,1....v)变成了按照拓扑序列开始遍历,多一个栈来存储Gr的逆后序,其他的都和标准的深度优先搜索一致。

但难就难在理解,为什么用Gr的逆反序进行dfs(s)可达v就能证明S,V是强连通的。

首先:dfs(s)可达v,是在Gr中,而Gr是G的反向图,则在G中,V->S是可达的。现在需要证明的就是通过这个dfs能证明s->v是可达的。

而我们知道,有向图的基于深度优先的顶点排序,前序是代表dfs()的调用顺序,后序是代表顶点遍历完成的顺序,逆后序从字面就能理解。

而在逆后序的栈中,s在v之前被遍历到,证明v是比s先入栈的,即先完成的结点。

因此根据DFS调用的递归性质,DFS(v)应该在DFS(s)之前返回,而有两种情形满足该条件:

  1. DFS(v) START -> DFS(v) END -> DFS(s) START -> DFS(s) END
  1. DFS(s) START -> DFS(v) START -> DFS(v) END -> DFS(s) END

是因为而根据目前的已知条件,GR中存在一条sv的路径,即意味着G中存在一条vs的路径,

而在第一种情形下:调用DFS(v)却没能在它返回前递归调用DFS(s)(即v->s不可达,与已知条件相悖),这是和G中存在vs的路径相矛盾的,因此不可取。

故情形二为唯一符合逻辑的调用过程。而根据DFS(s) START -> DFS(v) START可以推导出从sv存在一条路径。(符合dfs中for(int s:order.reverseOrder())即v是s可达的点。


原创粉丝点击