强连通分量算法(3)
Cheriyan–Mehlhorn/Gabow algorithm
这个算法的思路和tarjan算法差不多,效率要比tarjan算法快一点。
算法需要两个栈来进行维护。
下面这个伪代码是tarjan的伪代码修改过来的。从结构上看非常的相似。
1 algorithm gabow is
2
3 input: graph G = (V, E)
4
5 output: set of strongly connected components (sets of vertices)
6
7
8
9 index := 1
10
11 S1 := empty
12
13 S2 := empty
14
15 for each v in V do
16
17 if (v.index is undefined)
18
19 strongconnect(v)
20
21 end if
22
23 repeat
24
25
26
27 function strongconnect(v)
28
29 // Set the depth index for v to the smallest unused index
30
31 v.index := index
32
33 index := index + 1
34
35 S1.push(v)
36
37 S2.push(v)
38
39
40
41 // Consider successors of v
42
43 for each (v, w) in E do
44
45 if (w.index is undefined) then
46
47 // Successor w has not yet been visited; recurse on it
48
49 strongconnect(w)
50
51 else if (w is in S1) then
52
53 // Successor w is in stack S1 and hence in the current SCC
54
55 While( S2.top.index>w.index ) S2.top--;
56
57 end if
58
59 repeat
60
61
62
63 // If v is a root node, pop the stack and generate an SCC
64
65 if (i==S2.top) then
66
67 start a new strongly connected component
68
69 S2.top--;
70
71 repeat
72
73 w := S1.pop()
74
75 add w to current strongly connected component
76
77 until (w = v)
78
79 output the current strongly connected component
80
81 end if
82
83 end function
对于这样一个图:我们手动执行一遍程序
1. 第一步
DFN = [1]
S1 = [1]
S2 = [1]
2. 第二步
DFN=[1 2]
S1 = [1 3]
S2 =[1 3]
3. 第三步
DFN=[1 2 3]
S1 =[1 3 5]
S2 =[1 3 5]
4. 第四步
DFN=[1 2 3 4]
S1 = [1 3 5 6]
S2 = [1 3 5 6]
5. 第五步
I = 6
I = top of S2;
DFN=[1 2 3]
S1=[1 3 5]
S2=[1 3 5]
6. 第六步
I=5
I=top of S2
DFN=[1 2]
S1=[1 3]
S2=[1 3]
7. 第七步
I=3,继续搜
DFN = [1 2 5]
S1=[1 3 4]
S2=[1 3 4]
8. 第八步
I=4,继续搜
碰到1,已经存在于S1,那么要处理S2
DFN=[1 2 5]
S1=[1 3 4]
S2=[1]
9. 第九步
回到I=3
10. 第十步
回到I=1,继续搜
DFN=[1 2 5 6]
S1=[1 3 4 2]
S2=[1 2]
11. 第十一步
I=4,已经存在于S1中,处理S2
DFN=[1 2 5 6]
S1=[1 3 4 2]
S2=[1]
12. 第十二步
回到I=2
回到I=1
I==top of S2
从S1中弹出一个scc
S1 = []
S2 = []
算法执行完毕