Skip to content

Commit b461c40

Browse files
committed
seeing if iterative scc is any faster
1 parent 93b4a5b commit b461c40

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

library/graphs/strongly_connected_components/offline_incremental_scc.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ vi offline_incremental_scc(vector<array<int, 2>> eds,
3232
if (*it <= mid) adj[u].push_back(v);
3333
}
3434
rep(i, 0, sz(adj)) ids[vs[i]] = -1;
35-
scc_id = sccs(adj).scc_id;
35+
scc_id = sccs(adj).second;
3636
auto split = partition(el, er, [&](int i) {
3737
return scc_id[eds[i][0]] == scc_id[eds[i][1]];
3838
});

library/graphs/strongly_connected_components/scc.hpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,34 @@
77
//! for each edge u -> v: scc_id[u] >= scc_id[v]
88
//! @time O(n + m)
99
//! @space O(n)
10-
struct sccs {
11-
int num_sccs = 0;
12-
vi scc_id;
13-
sccs(const vector<vi>& adj): scc_id(sz(adj), -1) {
14-
int n = sz(adj), timer = 1;
15-
vi tin(n), st;
16-
auto dfs = [&](auto&& self, int v) -> int {
17-
int low = tin[v] = timer++, siz = sz(st);
18-
st.push_back(v);
19-
for (int u : adj[v])
20-
if (scc_id[u] < 0)
21-
low = min(low, tin[u] ? tin[u] : self(self, u));
22-
if (tin[v] == low) {
23-
rep(i, siz, sz(st)) scc_id[st[i]] = num_sccs;
24-
st.resize(siz);
25-
num_sccs++;
10+
pair<int, vector<int>> sccs(const vector<vector<int>>& adj) {
11+
int num_sccs = 0, n = ssize(adj), timer = 0;
12+
vector<int> scc_id(n, -1), tin(n), low(n), st, e(n), p(n, -1);
13+
for (int i = 0; i < n; i++)
14+
if (!tin[i]) {
15+
int v = i;
16+
while (v >= 0) {
17+
if (e[v]) {
18+
int u = adj[v][e[v] - 1];
19+
if (scc_id[u] == -1) low[v] = min(low[v], low[u]);
20+
} else {
21+
low[v] = tin[v] = ++timer;
22+
st.push_back(v);
23+
}
24+
if (e[v] < ssize(adj[v])) {
25+
int u = adj[v][e[v]++];
26+
if (!tin[u]) p[u] = v, v = u;
27+
} else {
28+
if (low[v] == tin[v]) {
29+
while (scc_id[v] == -1) {
30+
scc_id[st.back()] = num_sccs;
31+
st.pop_back();
32+
}
33+
num_sccs++;
34+
}
35+
v = p[v];
36+
}
2637
}
27-
return low;
28-
};
29-
rep(i, 0, n) if (!tin[i]) dfs(dfs, i);
30-
}
31-
};
38+
}
39+
return {num_sccs, scc_id};
40+
}

0 commit comments

Comments
 (0)