Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Linear-Time Algorithm for Finding Strongly Connected Components in Directed Graphs, Lecture notes of Algorithms and Programming

Notes on the linear-time algorithm for finding strongly connected components in directed graphs. The algorithm is based on two passes of depth-first search and involves reversing the graph and computing finishing times and leaders in two separate calls to the dfs-loop subroutine. An example to illustrate the working of the algorithm.

What you will learn

  • What is the role of depth-first search in the algorithm for computing strongly connected components?
  • What is the linear-time algorithm for computing the strongly connected components of a directed graph?
  • What is the key lemma that proves the correctness of the algorithm for computing strongly connected components?

Typology: Lecture notes

2018/2019

Uploaded on 01/26/2019

sam09
sam09 🇮🇳

2 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS161, Winter 2011 Handout #16
Notes on Strongly Connected Components
Recall from Section 3.5 of the Kleinberg-Tardos book that the strongly connected components of a directed
graph Gare the equivalence classes of the following equivalence relation: uvif and only if there is a directed
u vpath and also there is a directed v upath. (Check that this is indeed an equivalence relation.) For
example, in the directed graph in Figure 1, the strongly connected components are identified by the dashed
circles.
Figure 1: The strongly connected components of a directed graph.
1 The Algorithm
Goal of Lecture: to give a linear-time (i.e., O(m+n)-time) algorithm that computes the strongly connected
components of a directed graph.
The algorithm we present is essentially two passes of depth-first search, plus some extremely clever
additional book-keeping. The algorithm is described in a top-down fashion in Figures 2–4.
Input: a directed graph G= (V, E ), in adjacency list representation. Assume that the vertices Vare labeled
1,2,3,...,n.
1. Let Grev denote the graph Gafter the orientation of all arcs have been reversed.
2. Run the DFS-Loop subroutine on Grev , processing vertices according to the given order, to obtain a
finishing time f(v) for each vertex vV.
3. Run the DFS-Loop subroutine on G, processing vertices in decreasing order of f(v), to assign a leader
to each vertex vV.
4. The strongly connected components of Gcorrespond to vertices of Gthat share a common leader.
Figure 2: The top level of our SCC algorithm. The f-values and leaders are computed in the first and second
calls to DFS-Loop, respectively (see below).
1
pf3
pf4
pf5

Partial preview of the text

Download Linear-Time Algorithm for Finding Strongly Connected Components in Directed Graphs and more Lecture notes Algorithms and Programming in PDF only on Docsity!

CS161, Winter 2011 Handout #

Notes on Strongly Connected Components

Recall from Section 3.5 of the Kleinberg-Tardos book that the strongly connected components of a directed graph G are the equivalence classes of the following equivalence relation: u ∼ v if and only if there is a directed u v path and also there is a directed v u path. (Check that this is indeed an equivalence relation.) For example, in the directed graph in Figure 1, the strongly connected components are identified by the dashed circles.

Figure 1: The strongly connected components of a directed graph.

1 The Algorithm

Goal of Lecture: to give a linear-time (i.e., O(m+n)-time) algorithm that computes the strongly connected components of a directed graph. The algorithm we present is essentially two passes of depth-first search, plus some extremely clever additional book-keeping. The algorithm is described in a top-down fashion in Figures 2–4.

Input: a directed graph G = (V, E), in adjacency list representation. Assume that the vertices V are labeled 1 , 2 , 3 ,... , n.

  1. Let Grev^ denote the graph G after the orientation of all arcs have been reversed.
  2. Run the DFS-Loop subroutine on Grev^ , processing vertices according to the given order, to obtain a finishing time f (v) for each vertex v ∈ V.
  3. Run the DFS-Loop subroutine on G, processing vertices in decreasing order of f (v), to assign a leader to each vertex v ∈ V.
  4. The strongly connected components of G correspond to vertices of G that share a common leader.

Figure 2: The top level of our SCC algorithm. The f -values and leaders are computed in the first and second calls to DFS-Loop, respectively (see below).

Input: a directed graph G = (V, E), in adjacency list representation.

  1. Initialize a global variable t to 0. [This keeps track of the number of vertices that have been fully explored.]
  2. Initialize a global variable s to NULL. [This keeps track of the vertex from which the last DFS call was invoked.]
  3. For i = n downto 1:

[In the first call, vertices are labeled 1, 2 ,... , n arbitrarily. In the second call, vertices are labeled by their f (v)-values from the first call.]

(a) if i not yet explored: i. set s := i ii. DFS(G, i)

Figure 3: The DFS-Loop subroutine.

Input: a directed graph G = (V, E), in adjacency list representation, and a source vertex i ∈ V.

  1. Mark i as explored. [It remains explored for the entire duration of the DFS-Loop call.]
  2. Set leader(i) := s
  3. For each arc (i, j) ∈ G:

(a) if j not yet explored: i. DFS(G, j)

  1. t + +
  2. Set f (i) := t

Figure 4: The DFS subroutine. The f -values only need to be computed during the first call to DFS-Loop, and the leader values only need to be computed during the second call to DFS-Loop.

C 1

C 2

C 3

C 4

(a) SCC graph for Figure 1

C 3 C 2 C 1

(b) SCC graph for Figure 5(b)

Figure 6: The DAGs of the SCCs of the graphs in Figures 1 and 5(b), respectively.

Key Lemma: Consider two “adjacent” strongly connected components of a graph G: components C 1 and C 2 such that there is an arc (i, j) of G with i ∈ C 1 and j ∈ C 2. Let f (v) denote the finishing time of vertex v in some execution of DFS-Loop on the reversed graph Grev^. Then

max v∈C 1

f (v) < max v∈C 2

f (v).

Proof of Key Lemma: Consider two adjacent SCCs C 1 and C 2 , as they appear in the reversed graph Grev — where there is an arc (j, i), with j ∈ C 2 and i ∈ C 1 (Figure 7). Because the equivalence relation defining the SCCs is symmetric, G and Grev^ have the same SCCs; thus C 1 and C 2 are also SCCs of Grev^. Let v denote the first vertex of C 1 ∪ C 2 visited by DFS-Loop in Grev^. There are now two cases. First, suppose that v ∈ C 1 (Figure 7(a)). Since there is no non-trivial cycle of SCCs (Section 3.1), there is no directed path from v to C 2 in Grev^. Since DFS discovers everything reachable and nothing more, it will finish exploring all vertices in C 1 without reaching any vertices in C 2. Thus, every finishing time in C 1 will be smaller that every finishing time in C 2 , and this is even stronger than the assertion of the lemma. (Cf., the left and middle SCCs in Figure 5.) Second, suppose that v ∈ C 2 (Figure 7(b)). Since DFS discovers everything reachable and nothing more, the call to DFS at v will finish exploring all of the vertices in C 1 ∪ C 2 before ending. Thus, the finishing time of v is the largest amongst vertices in C 1 ∪ C 2 , and in particular is larger than all finishing times in C 1. (Cf., the middle and right SCCs in Figure 5.) This completes the proof.

C 1 C 2 i (^) j v

(a) All f -values in C 1 smaller than in C 2

C 1 C 2 i (^) j v

(b) v has the largest f -value in C 1 ∪ C 2

Figure 7: Proof of Key Lemma. Vertex v is the first in C 1 ∪ C 2 visited during the execution of DFS-Loop on Grev^.

3.3 The Final Argument

The Key Lemma says that traversing an arc from one SCC to another (in the original, unreversed graph) strictly increases the maximum f -value of the current SCC. For example, if fi denotes the largest f -value of a vertex in Ci in Figure 6(a), then we must have f 1 < f 2 , f 3 < f 4. Intuitively, when DFS-Loop is invoked

on G, processing vertices in decreasing order of finishing times, the successive calls to DFS peel off the SCCs of the graph one at a time, like layers of an onion. We now formally prove correctness of our algorithm for computing strongly connected components. Consider the execution of DFS-Loop on G. We claim that whenever DFS is called on a vertex v, the vertices explored — and assigned a common leader — by this call are precisely those in v’s SCC in G. Since DFS-Loop eventually explores every vertex, this claim implies that the SCCs of G are precisely the groups of vertices that are assigned a common leader. We proceed by induction. Let S denote the vertices already explored by previous calls to DFS (initially empty). Inductively, the set S is the union of zero or more SCCs of G. Suppose DFS is called on a vertex v and let C denote v’s SCC in G. Since the SCCs of a graph are disjoint, S is the union of SCCs of G, and v /∈ S, no vertices of C lie in S. Thus, this call to DFS will explore, at the least, all vertices of C. By the Key Lemma, every outgoing arc (i, j) from C leads to some SCC C′^ that contains a vertex w with a finishing time larger than f (v). Since vertices are processed in decreasing order of finishing time, w has already been explored and belongs to S; since S is the union of SCCs, it must contain all of C′. Summarizing, every outgoing arc from C leads directly to a vertex that has already been explored. Thus this call to DFS explores the vertices of C and nothing else. This completes the inductive step and the proof of correctness.