public class StronglyConnectedComponents {
private final int V;
private final LinkedList<Integer>[] adj;
StronglyConnectedComponents(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList<>();
}
void addEdge(int v, int w) {
adj[v].add(w);
}
void DFSUtil(int v, boolean[] visited, List<Integer> buff) {
visited[v] = true;
buff.add(v);
for (Integer n : adj[v]) {
if (!visited[n])
DFSUtil(n, visited, buff);
}
}
StronglyConnectedComponents getTranspose() {
StronglyConnectedComponents g = new StronglyConnectedComponents(V);
for (int v = 0; v < V; v++) {
for (Integer integer : adj[v]) g.adj[integer].add(v);
}
return g;
}
void fillOrder(int v, boolean[] visited, Stack<Integer> stack) {
visited[v] = true;
for (int n : adj[v]) {
if (!visited[n])
fillOrder(n, visited, stack);
}
stack.push(v);
}
List<List<Integer>> printSCCs() {
List<List<Integer>> loop = new ArrayList<>();
Stack<Integer> stack = new Stack<>();
boolean[] visited = new boolean[V];
Arrays.fill(visited, false);
for (int i = 0; i < V; i++)
if (!visited[i])
fillOrder(i, visited, stack);
StronglyConnectedComponents gr = getTranspose();
Arrays.fill(visited, false);
while (!stack.empty()) {
int v = stack.pop();
if (!visited[v]) {
List<Integer> buff = new ArrayList<>();
gr.DFSUtil(v, visited, buff);
loop.add(new ArrayList<>(buff));
}
}
return loop;
}
public static void main(String[] args) {
StronglyConnectedComponents g = new StronglyConnectedComponents(6);
g.addEdge(1, 0);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.addEdge(0, 3);
g.addEdge(3, 4);
System.out.println("Following are strongly connected components " + "in given graph ");
List<List<Integer>> loop = g.printSCCs();
for (List<Integer> list : loop) System.out.println(Arrays.toString(list.toArray()));
}
}