forked from DanielW48/HackPack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path*StronglyConnectedComponents.java
More file actions
59 lines (51 loc) · 1.59 KB
/
*StronglyConnectedComponents.java
File metadata and controls
59 lines (51 loc) · 1.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class StronglyConnectedComponents {
static int n, m, preCt = 0, numSccs = 0;
static graph g, meta;
static int[] pre, low, id;
static ArrayDeque<Integer> stk = new ArrayDeque<>();
public static void main (String[] args){
g = new graph(n);
for(int i = 0; i < m; ++i){
int a, b; //edge from a to b
g.edges[a].offer(b);
}
pre = new int[n];
low = new int[n];
id = new int[n];
Arrays.fill(pre, -1);
for(int i = n - 1; i >= 0; --i){
if(pre[i] == -1) dfs(i);
}
meta = new graph(numSccs);
for(int i = 0; i < n; ++i){
for(int j : (ArrayDeque<Integer>) g.edges[i]){
if(id[i] != id[j]) meta.edges[id[i]].offer(id[j]);
}
}
}
static void dfs(int idx){
low[idx] = pre[idx] = preCt++;
stk.push(idx);
for(int next : (ArrayDeque<Integer>) g.edges[idx]){
if(pre[next] == -1) dfs(next);
low[idx] = Math.min(low[idx], low[next]);
}
if(low[idx] == pre[idx]){
while(true){
int curr = stk.pop();
id[curr] = numSccs;
low[curr] = n;
if(curr == idx) break;
}
++numSccs;
}
}
static class graph{
int n;
ArrayDeque[] edges;
graph(int nn){
edges = new ArrayDeque[n = nn];
for(int i = 0; i < n; ++i) edges[i] = new ArrayDeque<>();
}
}
}