Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of Algorithm for finding articulation points or cut vertices of a graph

I have searched the net and could not find any explanation of a DFS algorithm for finding all articulation vertices of a graph. There is not even a wiki page.

From reading around, I got to know the basic facts from here. PDF

There is a variable at each node which is actually looking at back edges and finding the closest and upmost node towards the root node. After processing all edges it would be found.

But I do not understand how to find this down & up variable at each node during the execution of DFS. What is this variable doing exactly?

Please explain the algorithm.

Thanks.

like image 727
Ashish Negi Avatar asked Apr 08 '13 07:04

Ashish Negi


People also ask

How do you find 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 do you mean by articulation points or cut vertices in a graph?

Note: A vertex in an undirected connected graph is an articulation point (or cut vertex) if removing it (and edges through it) disconnects the graph. Articulation points represent vulnerabilities in a connected network – single points whose failure would split the network into 2 or more components.

Which of the following algorithms can be used to check whether a given vertex is articulation point or not?

Algorithm to Find All Articulation Points This is a Depth First Search (DFS) based algorithm to find all the articulation points in a graph. Given a graph, the algorithm first constructs a DFS tree. Initially, the algorithm chooses any random vertex to start the algorithm and marks its status as visited.


2 Answers

Finding articulation vertices is an application of DFS.

In a nutshell,

  1. Apply DFS on a graph. Get the DFS tree.
  2. A node which is visited earlier is a "parent" of those nodes which are reached by it and visited later.
  3. If any child of a node does not have a path to any of the ancestors of its parent, it means that removing this node would make this child disjoint from the graph.
  4. There is an exception: the root of the tree. If it has more than one child, then it is an articulation point, otherwise not.

Point 3 essentially means that this node is an articulation point.

Now for a child, this path to the ancestors of the node would be through a back-edge from it or from any of its children.

All this is explained beautifully in this PDF.

like image 65
Ashish Negi Avatar answered Oct 04 '22 18:10

Ashish Negi


I'll try to develop an intuitive understanding on how this algorithm works and also give commented pseudocode that outputs Bi-Components as well as bridges.

It's actually easy to develop a brute force algorithm for articulation points. Just take out a vertex, and run BFS or DFS on a graph. If it remains connected, then the vertex is not an articulation point, otherwise it is. This will run in O(V(E+V)) = O(EV) time. The challenge is how to do this in linear time (i.e. O(E+V)).

Articulation points connect two (or more) subgraphs. This means there are no edges from one subgraph to another. So imagine you are within one of these subgraphs and visiting its node. As you visit the node, you flag it and then move on to the next unflagged node using some available edge. While you are doing this, how do you know you are within still same subgraph? The insight here is that if you are within the same subgraph, you will eventually see a flagged node through an edge while visiting an unflagged node. This is called a back edge and indicates that you have a cycle. As soon as you find a back edge, you can be confident that all the nodes through that flagged node to the one you are visiting right now are all part of the same subgraph and there are no articulation points in between. If you didn't see any back edges then all the nodes you visited so far are all articulation points.

So we need an algorithm that visits vertices and marks all points between the target of back edges as currently-being-visited nodes as within the same subgraph. There may obviously be subgraphs within subgraphs so we need to select largest subgraph we have so far. These subgraphs are called Bi-Components. We can implement this algorithm by assigning each bi-component an ID which is initialized as just a count of the number of vertices we have visited so far. Later as we find back edges, we can reset the bi-compinent ID to lowest we have found so far.

We obviously need two passes. In the first pass, we want to figure out which vertex we can see from each vertex through back edges, if any. In the second pass we want to visit vertices in the opposite direction and collect the minimum bi-component ID (i.e. earliest ancestor accessible from any descendants). DFS naturally fits here. In DFS we go down first and then come back up so both of the above passes can be done in a single DFS traversal.

Now without further ado, here's the pseudocode:

time = 0 visited[i] = false for all i GetArticulationPoints(u)     visited[u] = true     u.st = time++     u.low = v.st    //keeps track of highest ancestor reachable from any descendants     dfsChild = 0    //needed because if no child then removing this node doesn't decompose graph     for each ni in adj[i]         if not visited[ni]             GetArticulationPoints(ni)             ++dfsChild             parents[ni] = u             u.low = Min(u.low, ni.low)  //while coming back up, get the lowest reachable ancestor from descendants         else if ni <> parent[u] //while going down, note down the back edges             u.low = Min(u.low, ni.st)      //For dfs root node, we can't mark it as articulation point because      //disconnecting it may not decompose graph. So we have extra check just for root node.     if (u.low = u.st and dfsChild > 0 and parent[u] != null) or (parent[u] = null and dfsChild > 1)         Output u as articulation point         Output edges of u with v.low >= u.low as bridges     output u.low as bicomponent ID 
like image 41
Shital Shah Avatar answered Oct 04 '22 18:10

Shital Shah