forked from kth-competitive-programming/kactl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSCC.h
41 lines (39 loc) · 1.19 KB
/
SCC.h
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
/**
* Author: Lukas Polacek
* Date: 2009-10-28
* License: CC0
* Source: Czech graph algorithms book, by Demel. (Tarjan's algorithm)
* Description: Finds strongly connected components in a
* directed graph. If vertices $u, v$ belong to the same component,
* we can reach $u$ from $v$ and vice versa.
* Usage: scc(graph, [\&](vi\& v) { ... }) visits all components
* in reverse topological order. comp[i] holds the component
* index of a node (a component only has edges to components with
* lower index). ncomps will contain the number of components.
* Time: O(E + V)
* Status: Bruteforce-tested for N <= 5
*/
#pragma once
vi val, comp, z, cont;
int Time, ncomps;
template<class G, class F> int dfs(int j, G& g, F& f) {
int low = val[j] = ++Time, x; z.push_back(j);
for (auto e : g[j]) if (comp[e] < 0)
low = min(low, val[e] ?: dfs(e,g,f));
if (low == val[j]) {
do {
x = z.back(); z.pop_back();
comp[x] = ncomps;
cont.push_back(x);
} while (x != j);
f(cont); cont.clear();
ncomps++;
}
return val[j] = low;
}
template<class G, class F> void scc(G& g, F f) {
int n = sz(g);
val.assign(n, 0); comp.assign(n, -1);
Time = ncomps = 0;
rep(i,0,n) if (comp[i] < 0) dfs(i, g, f);
}