# 强连通分量算法(2)

Tarjan's strongly connected components algorithm

Pku 2186,2553,1236,2762,都是可以用强连通分量算法来解决的。Kosaraju的算法在大部分情况下还是够用的，至少对于这四个题时间都还行。但是既然有更好的算法，那也学习一下吧。

The algorithm takes a directed graph as input, and produces a partition of the graph's vertices into the graph's strongly connected components. Every vertex of the graph appears in a single strongly connected component, even if it means a vertex appears in a strongly connected component by itself (as is the case with tree-like parts of the graph, as well as any vertex with no successor or no predecessor).

The basic idea of the algorithm is this: a depth-first search begins from an arbitrary start node (and subsequent depth-first searches are conducted on any nodes that have not yet been found). The search does not explore any node that has already been explored. The strongly connected components form the subtrees of the search tree, the roots of which are the roots of the strongly connected components.

The nodes are placed on a stack in the order in which they are visited. When the search returns from a subtree, the nodes are taken from the stack and it is determined whether each node is the root of a strongly connected component. If a node is the root of a strongly connected component, then it and all of the nodes taken off before it form that strongly connected component.

The crux of the algorithm comes in determining whether a node is the root of a strongly connected component. The concept of the "root" applies only to this algorithm (outside of the algorithm, a strongly connected component has no single "root" node). The root node is simply the first node of the strongly connected component which is encountered during the depth-first traversal. When a node is identified as the root node, once recursion on its successors has finished, all nodes on the stack from the root upwards form a complete strongly connected component.

To find the root, each node is given a depth search index v.index, which numbers the nodes consecutively in the order in which they are discovered. In addition, each node is assigned a value v.lowlink that is equal to the index of some node reachable from v, and always less than v.index, or equal to v.index if no other node is reachable from v. Therefore v is the root of a strongly connected component if and only if v.lowlink == v.index. The value v.lowlink is computed during the depth first search such that it is always known when needed.

algorithm tarjan is

input: graph G = (V, E)

output: set of strongly connected components (sets of vertices)

index := 0

S := empty

for each v in V do

if (v.index is undefined)

strongconnect(v)

end if

repeat

function strongconnect(v)

// Set the depth index for v to the smallest unused index

v.index := index

index := index + 1

S.push(v)

// Consider successors of v

for each (v, w) in E do

if (w.index is undefined) then

// Successor w has not yet been visited; recurse on it

strongconnect(w)

else if (w is in S) then

// Successor w is in stack S and hence in the current SCC

end if

repeat

// If v is a root node, pop the stack and generate an SCC

start a new strongly connected component

repeat

w := S.pop()

add w to current strongly connected component

until (w = v)

output the current strongly connected component

end if

end function


posted @ 2011-02-27 23:01  AC2012  阅读(522)  评论(0编辑  收藏