一:kosaraju算法
第一步:
对图进行后续遍历,用数组num记录每个节点访问的编号。(这里的后续遍历能够使得根节点的num值最大,从而保证比节点num值小的那些节点,根节点都可以访问到。)
第二步:
将原图边的方向倒转,然后从num值大的节点开始深度优先搜索。能够搜到的未删除的点的集合就是一个强连通子图。想象一下,如果第二步是从森林里选择树,那么哪个树是不连通(对于GT来说)到其他树上的呢?就是最后遍历出来的树,它的根节点在步骤1的遍历中离开时间最晚,而且可知它也是该树中离开时间最晚的那个节点。这给我们提供了很好的选择,在第一次深搜遍历时,记录时间i离开的顶点j,即numb[i]=j。那么,我们每次只需找到没有找过的顶点中具有最晚离开时间的顶点直接深搜(对于GT来说)就可以了。每次深搜都得到一个强连通分量。
隐藏性质:
分析到这里,我们已经知道怎么求强连通分量了。但是,大家有没有注意到我们在第二次深搜选择树的顺序有一个特点呢?如果在看上述思路的时候,你的脑子在思考,相信你已经知道了!!!它就是:如果我们把求出来的每个强连通分量收缩成一个点,并且用求出每个强连通分量的顺序来标记收缩后的节点,那么这个顺序其实就是强连通分量收缩成点后形成的有向无环图的拓扑序列。为什么呢?首先,应该明确搜索后的图一定是有向无环图呢?废话,如果还有环,那么环上的顶点对应的所有原来图上的顶点构成一个强连通分量,而不是构成环上那么多点对应的独自的强连通分量了。然后就是为什么是拓扑序列,我们在改进分析的时候,不是先选的树不会连通到其他树上(对于反图GT来说),也就是后选的树没有连通到先选的树,也即先出现的强连通分量收缩的点只能指向后出现的强连通分量收缩的点。那么拓扑序列不是理所当然的吗?这就是Kosaraju算法的一个隐藏性质。
证明如下:(转载)
命题1:该算法求出的都是强连通分量
假设在后来转置后的图中从xdfs到了 y处,说明存在路径x->y。因为这是在转置图中,所以说明原图中存在路径y->x。
然后另外一个信息就是x的序号在y之后。这有两种可能:
1、以y为根先DFS