int time = 0;
int[] ids;
int[] low;
boolean[] visited;
List<List<Integer>> res;
List<List<Integer>> graph;
Stack<Integer> stack;
boolean[] onStack;
public List<List<Integer>> getSCComponents(int n, List<List<Integer>> graph) {
ids = new int[n];
low = new int[n];
visited = new boolean[n];
this.graph = graph;
res = new ArrayList<>();
onStack = new boolean[n];
stack = new Stack<>();
for(int i = 0; i < n; i++) {
if (visited[i] == false) {
dfs(i);
}
}
return res;
}
private void dfs(int cur) {
ids[cur] = low[cur] = time++;
visited[cur] = true;
stack.push(cur);
onStack[cur] = true;
for(int to : graph.get(cur)) {
//if(to != -1) {//not sure
if(visited[to] == false) {
dfs(to);
low[cur] = Math.min(low[cur], low[to]);
} else {
if(onStack[to]) {
low[cur] = Math.min(low[cur], ids[to]);
}
}
}
//add item in stack to result
int item = 0;
if (low[cur] == ids[cur]) {
List<Integer> list = new ArrayList<>();
while(stack.peek() != cur) {
item = stack.peek();
list.add(item);
onStack[item] = false;
stack.pop();
}
item = stack.peek();
list.add(item);
res.add(list);
onStack[item] = false;
stack.pop();
}
}
//refer: https://iq.opengenus.org/tarjans-algorithm/
public static void main(String[] args) {
OATest oaTest = new OATest();
int n = 4;
List<Integer>[] graph = new List[n];
List<Integer> list0 = new ArrayList<>();
list0.add(0);
list0.add(1);
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
List<Integer> list2 = new ArrayList<>();
list2.add(2);
list2.add(0);
List<Integer> list3 = new ArrayList<>();
list3.add(1);
list3.add(3);
graph[0] = list0;
graph[1] = list1;
graph[2] = list2;
graph[3] = list3;
List<List<Integer>> res = oaTest.getSCComponents(graph);
System.out.println(res);
}
private int timer = 0;
public List<List<Integer>> getSCComponents(List<Integer>[] graph) {
int n = graph.length;
int[] low = new int[n];
boolean[] visited = new boolean[n];
Stack<Integer> stack = new Stack<>();
List<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (!visited[i]) {
helper(i, graph, res, visited, stack, low);
}
}
return res;
}
public void helper(int i, List<Integer>[] graph, List<List<Integer>> res, boolean[] visited, Stack<Integer> stack, int[] low) {
low[i] = timer;
timer++;
visited[i] = true;
stack.push(i);
int min = low[i];
for (int node : graph[i]) {
if (!visited[node]) {
helper(node, graph, res, visited, stack, low);
}
if (low[node] < min) {
min = low[node];
}
}
if (min < low[i]) {
low[i] = min;
return;
}
List<Integer> component = new ArrayList<>();
int w;
do
{
w = stack.pop();
component.add(w);
low[w] = graph.length;
} while (w != i);
res.add(component);
}
refer: https://www.sanfoundry.com/java-program-tarjan-algorithm/