I need to check if a directed graph is strongly connected, or, in other words, if all nodes can be reached by any other node (not necessarily through direct edge).
One way of doing this is running a DFS and BFS on every node and see all others are still reachable.
Is there a better approach to do that?
Consider the following algorithm.
Start at a random vertex
v
of the graphG
, and run aDFS(G, v)
.If
DFS(G, v)
fails to reach every other vertex in the graphG
, then there is some vertexu
, such that there is no directed path fromv
tou
, and thusG
is not strongly connected.If it does reach every vertex, then there is a directed path from
v
to every other vertex in the graphG
.Reverse the direction of all edges in the directed graph
G
.Again run a
DFS
starting atv
.If the DFS fails to reach every vertex, then there is some vertex
u
, such that in the original graph there is no directed path fromu
tov
.On the other hand, if it does reach every vertex, then in the original graph there is a directed path from every vertex
u
tov
.Thus, if G "passes" both DFSs, it is strongly connected. Furthermore, since a DFS runs in
O(n + m)
time, this algorithm runs inO(2(n + m)) = O(n + m)
time, since it requires 2 DFS traversals.Tarjan's Algorithm has been already mentioned. But I usually find Kosaraju's Algorithm easier to follow even though it needs two traversals of the graph. IIRC, it is also pretty well explained in CLRS.