Given a directed graph, check if it is strongly connected or not. A directed graph is said to be strongly connected if every vertex is reachable from every other vertex.

For example, the following graph is strongly connected as a path exists between all pairs of vertices:

Strongly Connected Graph

 
Prerequisite:

Arrival and departure time of vertices in DFS

Types of edges involved in DFS and relation between them

Practice this problem

In the previous post, we have discussed a solution that requires two DFS traversals of a graph. We can check if the graph is strongly connected or not by doing only one DFS traversal on the graph.

When we do a DFS from a vertex v in a directed graph, there could be many edges going out of its subtree. When we say subtree rooted at v, we mean all v's descendants, including the vertex itself. The edges going out of the subtree will either be a back edge or a cross edge. Forward edges cannot be going out of the subtree as they can only be coming into the subtree, or if it starts from within the subtree, it will go within the subtree only.

We can say that the graph is strongly connected if and only if for every edge u —> v in the graph, there is at least one back-edge or cross-edge that is going out of the subtree rooted at v.

How should we modify DFS so that we can check if there is an out-edge going out of every subtree?

We can modify DFS such that DFS(v) returns the smallest arrival time to which there is an out-edge from the subtree rooted at v. For example, let arrival(v) be the arrival time of vertex v in the DFS. Then if there is an edge out of the subtree rooted at v, it is to something visited before v and therefore with a smaller arrival value.

Remember for a back edge or a cross edge, u —> v, arrival[u] > arrival[v].

Suppose there are four edges going out of the subtree rooted at v to vertex a, b, c, and d with arrival time arrival(a), arrival(b), arrival(c), and arrival(d), respectively. We look at their arrival times and consider the smallest among them. That will be the value returned by DFS(v), i.e., DFS(v) returns minimum min of arrival(a), arrival(b), arrival(c) and arrival(d). But before returning, we have to check that min is less than the arrival(v). If min is less than the arrival(v), then that means that at least one back-edge or cross edge is going out of the subtree rooted at v. If not, then we can stop the procedure and say that the graph is not strongly connected.

This is demonstrated below in C++, Java, and Python:

C++


Download  Run Code

Output:

The graph is strongly connected

Java


Download  Run Code

Output:

The graph is strongly connected

Python


Download  Run Code

Output:

The graph is strongly connected

The time complexity of the above solution is O(V + E), where V and E are the total number of vertices and edges in the graph, respectively. Please note that O(E) may vary between O(1) and O(V2), depending on how dense the graph is.

 
Reference: Dr. Naveen Garg, IIT–D (Lecture – 30 Applications of DFS in Directed Graphs)