Skip to Content
Team NoteAlgorithmStrongly Connected Components (SCC)

Strongly Connected Components (SCC)

class SCC { public: vvi edges, scc, scc_edges; vi sn, dfsn, fin, entry, in, out; int N, next_dfsn = 0, size = 0; SCC(int N) : N(N) { edges.resize(N); sn.resize(N); dfsn.resize(N, -1); fin.resize(N, 0); } void add_edge(int from, int to) { edges[from].pb(to); } void find() { for (int i = 0; i < N; i++) if (dfsn[i] == -1) dfs(i); } void find_scc_edges() { scc_edges.resize(size); entry.resize(size); in.resize(size); out.resize(size); for (int i = 0; i < N; i++) for (int j: edges[i]) if (sn[i] != sn[j]) { scc_edges[sn[i]].pb(sn[j]); entry[sn[j]]++; out[sn[i]]++; in[sn[j]]++; } } void add_or(int x, int y) { add_edge(x ^ 1, y); add_edge(y ^ 1, x); } void add_xor(int x, int y) { add_or(x, y); add_or(x ^ 1, y ^ 1); } void add_onezero(int x, int y, int z) { add_or(x ^ 1, y ^ 1); add_or(y ^ 1, z ^ 1); add_or(z ^ 1, x ^ 1); } vi two_sat() { for (int i = 0; i < N; i++) if (sn[i] == sn[i ^ 1]) return {}; vi ans(N >> 1, -1); for (int i = size - 1; i >= 0; i--) for (int n: scc[i]) if (ans[n >> 1] == -1) ans[n >> 1] = !(n & 1); return ans; } private: stack<int> s; int dfs(int cur) { dfsn[cur] = next_dfsn++; s.push(cur); int low = dfsn[cur]; for (int to: edges[cur]) { if (!fin[to]) { if (dfsn[to] == -1) low = min(low, dfs(to)); else low = min(low, dfsn[to]); } } if (low == dfsn[cur]) { vi tmp; while (1) { int popped = s.top(); s.pop(); fin[popped] = true; sn[popped] = size; tmp.pb(popped); if (popped == cur) break; } size++; scc.pb(tmp); } return low; } };
Last updated on