-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy path*SCCs.java
More file actions
76 lines (69 loc) · 1.4 KB
/
*SCCs.java
File metadata and controls
76 lines (69 loc) · 1.4 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
static class SCCs {
int n;
graph g;
int preCount, metaN, stkSize;
int[] pre, low, map, stk;
// returns DAG meta graph
graph getMeta(graph gg) {
g = gg;
n = g.n;
// do lowlink
preCount = -1;
metaN = 0;
pre = new int[n];
Arrays.fill(pre, -1);
low = new int[n];
map = new int[n]; // maps each node in original graph g to new node index in meta
stk = new int[n];
stkSize = 0;
for(int i = 0; i < n; ++i) {
if(pre[i] == -1) dfs(i);
}
graph meta = new graph(metaN);
for(int u = 0; u < n; ++u) {
for(edge e : g.edges[u]) {
if(map[u] != map[e.v]) meta.addEdge(map[u], map[e.v], e.w);
}
}
return meta;
}
void dfs(int idx) {
low[idx] = pre[idx] = ++preCount;
stk[stkSize++] = idx;
for(edge e : g.edges[idx]) {
if(pre[e.v] == -1) dfs(e.v);
if(low[e.v] < low[idx]) low[idx] = low[e.v];
}
if(low[idx] == pre[idx]) pop(idx);
}
void pop(int stop) {
while(stkSize > 0) {
int curr = stk[--stkSize];
map[curr] = metaN;
low[curr] = n;
if(curr == stop) break;
}
++metaN;
}
}
static class graph {
int n;
ArrayDeque<edge>[] edges;
graph(int nn){
edges = new ArrayDeque[n = nn];
for(int i = 0; i < n; ++i) edges[i] = new ArrayDeque<>();
}
void addEdge(int u, int v) {
addEdge(u, v, 1);
}
void addEdge(int u, int v, int w) {
edges[u].add(new edge(v, w));
}
}
static class edge{
int v, w;
edge(int vv, int ww){
v = vv;
w = ww;
}
}