SCC (Kosaraju)

O(n + m)

Strongly connected components of a directed graph in two passes: a postorder over the graph, then a sweep over the reverse graph in reverse postorder. Iterative, so deep graphs are safe. Component ids come out in topological order of the condensation, which is usually what the follow-up DP wants.

// use it on

CSES: Planets and Kingdoms

Label each planet with its kingdom, which is literally the comp[] array this template produces.

// the code

struct SCC {  // comp[v] = component id, in topological order
    int n, comps = 0;
    vector<vector<int>> adj, radj;
    vector<int> comp;
    SCC(int n) : n(n), adj(n), radj(n), comp(n, -1) {}
    void add_edge(int u, int v) {
        adj[u].push_back(v);
        radj[v].push_back(u);
    }
    void run() {
        vector<int> order, it(n, 0), st;
        vector<bool> seen(n, false);
        for (int s = 0; s < n; s++) {  // iterative postorder
            if (seen[s]) continue;
            seen[s] = true;
            st.push_back(s);
            while (!st.empty()) {
                int u = st.back();
                if (it[u] < (int)adj[u].size()) {
                    int v = adj[u][it[u]++];
                    if (!seen[v]) { seen[v] = true; st.push_back(v); }
                } else {
                    order.push_back(u);
                    st.pop_back();
                }
            }
        }
        for (int i = n - 1; i >= 0; i--) {  // sweep reverse graph
            if (comp[order[i]] != -1) continue;
            vector<int> q = {order[i]};
            comp[order[i]] = comps;
            while (!q.empty()) {
                int u = q.back();
                q.pop_back();
                for (int v : radj[u])
                    if (comp[v] == -1) { comp[v] = comps; q.push_back(v); }
            }
            comps++;
        }
    }
};