A directed graph is strongly connected if there is a path between all pairs of vertices. A strongly connected component (SCC) of a directed graph is a maximal strongly connected subgraph. For example, there are 3 SCCs in the following graph.
We can find all strongly connected components in O(V+E) time using Kosaraju’s algorithm. Following is detailed Kosaraju’s algorithm.
1) Create an empty stack ‘S’ and do DFS traversal of a graph. In DFS traversal, after calling recursive DFS for adjacent vertices of a vertex, push the vertex to stack. In the above graph, if we start DFS from vertex 0, we get vertices in stack as 1, 2, 4, 3, 0.
2) Reverse directions of all arcs to obtain the transpose graph.
3) One by one pop a vertex from S while S is not empty. Let the popped vertex be ‘v’. Take v as source and do DFS (call DFSUtil(v)). The DFS starting from v prints strongly connected component of v. In the above example, we process vertices in order 0, 3, 4, 2, 1 (One by one popped from stack).
publicclasssolution {publicstaticvoidfillStackDFS(int v,ArrayList<Integer>[] graph,Stack<Integer> st,boolean[] visited) { visited[v] =true;for (int x : graph[v])if (!visited[x])fillStackDFS(x, graph, st, visited);st.push(v); }publicstaticvoidfillStack(ArrayList<Integer>[] graph,Stack<Integer> st) {boolean visited[] =newboolean[graph.length];for (int i =0; i <graph.length; i++)if (!visited[i])fillStackDFS(i, graph, st, visited); }publicstaticArrayList<Integer>[] reverseGraph(ArrayList<Integer>[] graph) {ArrayList<Integer>[] graphReverse =newArrayList[graph.length];for (int i =0; i <graph.length; i++) graphReverse[i] =newArrayList<>();for (int i =0; i <graph.length; i++)for (int x : graph[i]) graphReverse[x].add(i);return graphReverse; }publicstaticvoidfindSCCDFS(int v,ArrayList<Integer>[] graph,boolean[] visited,ArrayList<Integer> SCC) { visited[v] =true;SCC.add(v);for (int x : graph[v])if (!visited[x])findSCCDFS(x, graph, visited, SCC); }publicstaticArrayList<ArrayList<Integer>> allSCComponents(Stack<Integer> st,ArrayList<Integer>[] graph) {boolean visited[] =newboolean[graph.length];ArrayList<ArrayList<Integer>> ans =newArrayList<>();while (st.size() !=0) {int v =st.pop();if (!visited[v]) {ArrayList<Integer> SCC =newArrayList<>();findSCCDFS(v, graph, visited, SCC);ans.add(SCC); } }return ans; }publicstaticArrayList<ArrayList<Integer>> findAllSCC(ArrayList<Integer>[] graph) {Stack<Integer> st =newStack<>();fillStack(graph, st);ArrayList<Integer>[] graphReverse =reverseGraph(graph);returnallSCComponents(st, graphReverse); }publicstaticvoidmain(String args[]) {Scanner s =newScanner(System.in);int v =s.nextInt();int e =s.nextInt();ArrayList<Integer>[] graph =newArrayList[v];for (int i =0; i <graph.length; i++) graph[i] =newArrayList<>();for (int i =0; i < e; i++) {int v1 =s.nextInt();int v2 =s.nextInt(); graph[v1].add(v2); }ArrayList<ArrayList<Integer>> ans =findAllSCC(graph);for (ArrayList<Integer> x : ans) {for (int elem : x)System.out.print(elem +" ");System.out.println(); }s.close(); }}