Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to output all biconnected components of an undirected graph?

Given a general undirected graph, how can we print all the biconnected components of the graph in O(N+M) time? I know Tarjan's algorithm that is used to output all the articulation points of an undirected graph but I am finding it hard to extend the algorithm to print the biconnected components. I tried searching google but all the results that I got are not working on my test cases as they miss out on edge cases of the algorithm.

Can someone please provide working code for this problem.

Def: A biconnected component is a connected subgraph containing no vertex whose deletion would disconnect the subgraph.

Edit: I have successfully implemented the algorithm as described in this link provided by Niklas. Now I have a different question, how can I find out sub graphs of an undirected graph containing no edge whose deletion would disconnect the subgraph. Please help me solve this alternate problem as well.

like image 789
Nikunj Banka Avatar asked Feb 12 '14 16:02

Nikunj Banka


People also ask

How do you find the biconnected components of a graph?

We can find the biconnected components of a connected undirected graph, G, by using any depth first spanning tree of G. For example, the function call dfs (3) applied to the graph of Figure 6.19(a) produces the spanning tree of Figure 6.20(a).

How do you find all articulation points on a graph?

Articulation Points represents vulnerabilities in a network. In order to find all the articulation points in a given graph, the brute force approach is to check for every vertex if it is an articulation point or not, by removing it and then counting the number of connected components in the graph.

What is meant by biconnected components?

(definition) Definition: A maximal subset of edges of a connected graph such that the corresponding induced subgraph cannot be disconnected by deleting any vertex.


2 Answers

It's a classical problem with a known linear-time algorithm. You will probably need to decompose the graph into connected components first, though. Algorithm description from Wikipedia:

The classic sequential algorithm for computing biconnected components in a connected undirected graph due to John Hopcroft andRobert Tarjan (1973) [1] runs in linear time, and is based on depth-first search. This algorithm is also outlined as Problem 22-2 of Introduction to Algorithms (both 2nd and 3rd editions). The idea is to run a depth-first search while maintaining the following information: the depth of each vertex in the depth-first-search tree (once it gets visited), and for each vertex v, the lowest depth of neighbors of all descendants of v in the depth-first-search tree, called the lowpoint. The depth is standard to maintain during a depth-first search. The lowpoint of v can be computed after visiting all descendants of v (i.e., just before v gets popped off the depth-first-search stack) as the minimum of the depth of v, the depth of all neighbors of v (other than the parent of v in the depth-first-search tree) and the lowpoint of all children of v in the depth-first-search tree. The key fact is that a nonroot vertex v is a cut vertex (or articulation point) separating two biconnected components if and only if there is a child y of v such that lowpoint(y) ≥ depth(v). This property can be tested once the depth-first search returned from every child of v (i.e., just before v gets popped off the depth-first-search stack), and if true, v separates the graph into different biconnected components. This can be represented by computing one biconnected component out of every such y (a component which contains y will contain the subtree of y, plus v), and then erasing the subtree of y from the tree.The root vertex must be handled separately: it is a cut vertex if and only if it has at least two children. Thus, it suffices to simply build one component out of each child subtree of the root (including the root).

A good pseudo-code implementation can be found at http://www.cs.umd.edu/class/fall2005/cmsc451/biconcomps.pdf.

like image 186
Niklas B. Avatar answered Nov 16 '22 00:11

Niklas B.


Have a look at this PhD thesis on Planarity Testing by Path Addition.

Chapter 5 gives pseudo code for a DFS algorithm (two versions using recursion or iteration) and an algorithm to partition (decompose) the DFS tree (also known as a Tremaux tree) into a hierarchy of path segments (or chains). Chapter 4 gives a classification of these path segments into 4 different types depending on where the tail of the path segment connects in the DFS tree (relative to the path segment's head).

Given this separation, you can partition the tree into biconnected components such that:

  • Class 1 path segments are not part of any biconnected component;
  • Class 2 (minus the edges & vertices succeeding the segment's head and preceding the tail which, like Class 1 segments, are not part of any biconnected component) and Class 3 path segments form a loop and are at the start (root) of a biconnected component; and
  • Class 4 segments are part of a biconnected component which contains their most recent Class 2 or 3 ancestor path segment.

If correctly done, you should be able to extract these biconnected components in O(V+E) time.

There is Java source code at the back of the thesis which does a full planarity test in O(V+E) time & memory which may give you some further pointers (and extracts all permutations P of embeddings of the biconnected components in O(P(V+E))).

like image 26
MT0 Avatar answered Nov 16 '22 01:11

MT0