Tarjan's strongly connected components algorithm

From Wikipedia, the free encyclopedia

Tarjan's Algorithm (named for its discoverer, Robert Tarjan) is a graph theory algorithm for finding the strongly connected components of a graph.

Contents

[edit] Idea

The basic idea of the algorithm is this: a depth-first search begins from a start node. 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.

[edit] The Root Property

It is obviously crucial for the algorithm that when returning from a subtree it is determined for each node whether that node is in the root of a strongly connected component. For that purpose, each node is given a depth search index v.dfs, which numbers the nodes consecutively in the order in which they are "discovered" by the depth first search. In addition, a value v.lowlink is assigned, such that v.lowlink := min {v'.dfs: v' is reachable from v}. Therefore: v is the root of a strongly connected component if and only if v.lowlink = v.dfs. v.lowlink can be computed during the depth first search in such a way that the value is known at the time of the query.

[edit] The Algorithm in pseudocode

Input: Graph G = (V, E), Start node v0

max_dfs := 0  // Counter for dfs
U := V        // Collection of unvisited nodes
S := {}       // An initially empty stack
tarjan(v0)    // Call the function with the start node
procedure tarjan(v)
v.dfs := max_dfs;          // Set the depth index
v.lowlink := max_dfs;      // v.lowlink <= v.dfs
max_dfs := max_dfs + 1;    // Increment the counter
S.push(v);                 // Place v on the stack
U := U \ {v};              // Separate v from U
forall (v, v') in E do     // Consider the neighboring nodes
  if (v' in U)
    tarjan(v');            // recursive call
    v.lowlink := min(v.lowlink, v'.lowlink);
  // Ask whether v' is on the stack 
  // by a clever linear time method
  // (for example, setting a flag on the node when it is pushed or popped) 
  elseif (v' in S)
    v.lowlink := min(v.lowlink, v'.dfs);
  end if
end for
if (v.lowlink = v.dfs)     // the root of a strongly connected component
  print "SZK:";
  repeat
    v' := S.pop;
    print v';
  until (v' = v);
end if

[edit] Remarks

  1. Complexity: The tarjan procedure is called once for each node; the forall statement considers each edge at most twice. The algorithm's running time is therefore linear in the number of edges in G.
  2. Naturally, the algorithm can only find those strongly connected components that are reachable from the start node. Otherwise, the algorithm must be started several times from different start nodes.

[edit] Literature

  • Robert Tarjan: Depth-first search and linear graph algorithms. In: SIAM Journal on Computing. Vol. 1 (1972), No. 2, P. 146-160.

[edit] Links

Description of Tarjan's Algorithm

In other languages