对用2遍dfs求有向图强连通分量的理解

第一遍dfs是对原图进行,求出每个结点的后序遍历顺序,也叫时间戳,注意保存方式,应该是保存每个时间点的访问的结点,而不是保存每个结点的访问时间;
第二遍dfs是对逆图进行,根据第一遍dfs的结果,首先在逆图上从时间戳最大的结点开始dfs,可以得到第一个强连通分量,将遍历过的结点标记,然后从下一个时间戳最大的且尚未标记的结点开始dfs,可以得到第二个强连通分量,以此类推,直到所有结点都确定其所在的强连通分量,此时算法结束。

首先分析由此算法得到的第一个强连通分量的正确性,易知时间戳最大的是有向图的根结点:
1、从根结点出发,可以到达所有结点;
2、第二遍dfs是在逆图上进行的,所以第二遍dfs得到的是所有能到达根结点的结点。
由以上2点和强连通分量的定义可知,第二遍dfs得到的确实是根结点所在的强连通分量。

然后考虑将第一个强连通分量所包含的结点从原图中去掉(标记),则得到一个有向图的森林(可能含有多个根结点),时间戳最大的结点是森林中的某个根结点,问题转化为以上讨论过的形式,在此不再重复。

以上所说的“从根结点出发,可以到达所有结点”其实是有问题的……
另一种稍微严谨的分析:
首先证明一个结论:若从时间戳较小的结点a出发可以到达时间戳较大的结点b,那么从结点b出发一定可以到达结点a

反证法:假设a的后序遍历时间戳<b的时间戳,从a可达b,但从b不可达a,则该图至少有2个强连通分量,第一遍dfs存在2中情况:
情况1:a所在的强连通分量在第一遍dfs时先于b所在的强连通分量,由于a可达b,所以b的后序遍历时间戳将小于a的时间戳,与条件矛盾;
情况2:b所在的强连通分量在第一遍dfs时先于a所在的强连通分量,由于b不可达a,所以b的后序遍历时间戳将小于a的时间戳,与条件矛盾。

终上所述,结论得证。

有了以上结论,第二遍dfs就好理解了,第二遍dfs是从当前时间戳最大的结点开始的,且是对逆图进行dfs,所以找到的都是时间戳小于当前结点的且在原图上能到达当前结点的所有结点,根据以上结论,所以当前结点能到达所有这些找到的结点,所以就找到了当前结点所在的强连通分量所含的结点。

posted @ 2012-07-05 12:15  BeatLJ  阅读(1615)  评论(0编辑  收藏  举报