Lecture 24--Biconnected components of a graph. 11/21/97.
================================================================
24.1. Depth first search revisited. Recall the depth first search algorithm which we have already looked at. In this algorithm suppose that we initially mark all vertices of the graph G = (V,E) "unvisited". Then the first time we arrive at a vertex w we mark it "visited" and begin a depth first search from w. Now when we first arrive at an unvisited vertex w we are traveling along some edge (v,w). If we collect these edges into a set, we have a tree T of edges in G. If G is connected, T is a spanning tree; otherwise T is a forest of spanning trees, one for each component of G. We call the elements in E - T the "back edges" of G (note that T and B are not uniquely defined). See the example in figure 8. Clearly the depth first search procedure can be completed in O(max(n,m)) steps. Also, depth-first search can be used to number the vertices in order, by giving vertex v the number i if it is the ith vertex to be marked "visited".
We will need the following lemma:
Lemma. If (v,w) is a back edge, then in the spanning forest of G, v is an ancestor of w or vice versa.
Proof. We may suppose v is visited before w. Now when depth first search is called recursively from v, all unvisited vertices which are going to be marked visited will be descendants of v. But the recursive call from v cannot end until w has been visited.
24.2. Articulation points. Biconnectivity. In many applications involving transportation or communication networks, it is important to identify points through which all network traffic must flow (such as, for example, the Cincinnati airport). We assume G = (V,E) is connected and undirected. We say that vertex a of G is an articulation point if there are vertices v,w, with v <> w, such that all paths in G which go from v to w must pass through a. Alternatively, removing a (and its incident edges) from G would split G into two or more components (Figure 9). We say that G is biconnected if for every triple of distinct vertices in G, v,w,a, there exists a path from v to w not containing a, i.e., if G has no articulation points.
This notion leads to a relation on the set of edges of G defined as follows:
e and e' are related if e = e' or if there is a cycle containing both e and e'.
Exercise 24.1 Show that this is an equivalence relation on the edges of G (i.e., a reflexive, symmetric, and transitive relation).
Exercise 24.2. Show that the equivalence relation partitions e into equivalence classes Ei, such that if Vi is the set of vertices incident with edges in Ei, then
a. Each Ei consists of edges which lie on a common cycle
b. each graph Gi = (Vi, Ei) is a biconnected component of G.
(Note that the sets Vi are not necessarily disjoint).
Exercise 24.3. Find the biconnected components of the graph in Figure 10.
Lemma. For 1 <= i <= k let Gi = (Vi,Ei) be the biconnected components of G. Then
a. For each i, Gi is biconnected.
b. for i <> j, Vi intersects Vj in at most one vertex
c. a is an articulation point of G if and only if a is contained in Vi intersect Vj for some i <> j.
Proof.
a. Suppose there are three distinct vertices v,w,a in Vi such that all paths in Gi pass through a. Then (v,w) is not an edge in Ei. Thus there must be two distinct edges (v,v') and (w,w') in Ei and a cycle in Gi containing these edges. By the definition of the biconnected component Gi, all edges and vertices on this cycle must lie in Ei and Vi respectively. So there are two paths in Gi between v and w, and only one of these can contain a. But this is a contradiction.
b. Suppose there exist i and j <> i with Vi intersect Vj containing two distinct vertices, v and w. Then there exist cycles ci in Gi and cj in Gj containing v and w. The edges in these cycles are disjoint, but we may construct a cycle containing some edges from Ei and some edges from Ej and also containing v and w. But this is a contradiction, since Ei and Ej are equivalence classes and therefore disjoint.
c. If a is an articulation point of G then there exist vertices v and w with every path from v to w containing a. Choose one such path and let (x,a) and (a,y) be the edges on this path incident with a. Since a is an articulation point, there is no cycle containing these two edges, and so (x,a) and (y,a) are is different biconnected components, with a in the intersection of the vertex sets of these two components.
Conversely, if a is in Vi intersect Vj , then there are edges (x,a) in Ei and (a,y) in Ej. These edges do not occur on any one cycle, so every path from x to y contains a, and therefore a is an articulation point.
Lemma. If G = (V,E) is a connected graph and S = (V,T) is a depth-first spanning tree for G, then a is an articulation point of G if and only if
either
a. a is the root of S and a has more than one child
or
b. a is not the root and for some child c of a there is no back edge between any descendant of c (including c itself) and a proper ancestor of a.
Proof.
a. If a is the root and a is an articulation point then by the previous lemma a is in two biconnected components of G. Then a must have a child in each of these biconnected components. On the other hand, if a has more than one child then if a is not an articulation point there must be an edge between two of the children of a. Suppose v and w are such children and v is visited first. Then w will be visited before a is returned to and so w will not be a child of a. Since this is a contradiction it must be true that any two children of a (and their descendants) have no edges between them, so a is an articulation point of G.
b. Now suppose a is an articulation point but not the root. Let x and y be distinct vertices of G, not equal to a, with every path in G from x to y going through a. One of these vertices, say x, must be a proper descendant of a in S. Let c be the child of a such that x is a descendant of c (possibly c = x). Now if there is no back edge between a descendant v of c and a proper ancestor w of a we are done. So suppose there is such an edge. Now either y is not a descendant of a or y is a descendant of a. If y is not a descendant of a, then there is a path from x to v to w to y which avoids a. But this is a contradiction. If y is a descendant of a, then y cannot be a descendant of v but must be the descendant of some child c' of a. If there is no back edge between a descendant v' of c' and a proper ancestor w' of a, we are done. If there is such a back edge, then there is a path from x to v to w' to v' to y which avoids a. but this is also a contradiction, (See figures 11a and 11b).
Now if the condition in b is true, we wish to prove that a is an articulation point. Let p be the parent of a. Now any back edge v from a descendant of c must go to an ancestor of v. Since, by the hypothesis of the lemma, it cannot go to a proper ancestor of a, it must go either to a or to a descendant of c. So every path from c to p contains a, and therefore a is an articulation point.
Now suppose that T and B are the tree edges and the back edges of a connected undirected graph G, found by a depth first search. Assume the vertices of G have been labeled by the order in which they were visited in the depth first search. Define
LOW[v] = the minimum of v and the set of vertices w for which
there is a back edge (x,w) with x a
descendant of v and w an ancestor of v
Now the lemma we have just proved implies that if v is not the
root then v is an articulation point if and only if v has a child
c such that LOW[c] >= v. We can thus modify depth first
search to find the biconnected components of G by using this fact.
The algorithm below runs in time O(|E|) and can be proved correct by induction on the number of biconnected components.
Let T be empty and Count be 1. Mark each vertex "unvisited".
Also initialize a STACK of edges, initially empty.
Choose an initial v in V arbitrarily.
Then call BICONSEARCH(v).
BICONSEARCH(v).
mark v "visited"
dfsnum[v] = Count
++Count
for each vertex w in adjlist(v) do
if (v,w) is not on the STACK, push (v,w)
( (v,w) is on STACK if either
v < w and w already "visited" or
v > w and w = parent[v] )
if w is "unvisited" then
add (v,w) to T; set parent(w) = v;
BICONSEARCH(w)
if LOW[w] >= dfsnum[v] then a biconnected component
has been found;
pop the edges up to and including
(v,w); these are the component
LOW[v] = min (LOW[v],LOw[w])
else if w is not parent[v] then
LOW[v] = min(LOW[v], dfsnum[w])
See diagram 5.12.
Exercise 24.4. Show the steps in the algorithm applied to the graph in figure 10.