Strongly Connected Component – Tarjan Algorithm

#include<bits/stdc++.h>
#define ll long long

struct Tarjan // find all strongly connected components of a directed graph
{
    // NOTE: 
    //      vertex-index can be either 0-BASED or 1-BASED
    //      edge is ONE-WAY
    //      return all Strongly-Connected-Components with length >= 2
    
    int n; // number of vertice
    vector< vector<int> > adj;
    int *num;
    int *low;
    int *visited;
    int cnt;
    vector< vector<int> > sccs;
    stack<int> stk;
    
    void init(int n_) {
        n = n_;
        adj.resize(0);
        adj.resize(n+1);
        
        num = new int[n+1];
        low = new int[n+1];
        visited = new int[n+1];
    }
    
    void addEdge(int u, int v) {
        adj[u].push_back(v);
    }
    
    void dfs_scc(int u) {
        num[u] = low[u] = ++cnt;
        stk.push(u);
        
        for (int v : adj[u]) {
            if (!visited[v]) { 
                if (num[v] < 0) {
                    dfs_scc(v);
                    low[u] = min(low[u], low[v]);
                }
                else {
                    low[u] = min(low[u], num[v]);
                }
            }               
        }
        
        if (num[u] == low[u]) {
            
            vector<int> scc;
            
            while (true) {
                int top = stk.top();
                stk.pop();
                scc.push_back(top);
                visited[top] = 1;
                
                if (top == u)
                    break;
            }
            
            sccs.push_back(scc);
        }
        
    }
    
    vector< vector<int> >findSCC() {
        
        sccs.clear();
        while(!stk.empty()) stk.pop();  
        cnt = 0;
        for (int i = 0; i <= n; ++i) {
            num[i] = -1;
            low[i] = -1;
            visited[i] = 0;
        }
        
        for (int i = 0; i <= n; ++i)
            if (!visited[i])
                dfs_scc(i);
        
        return sccs;
    }
    
};

Leave a Reply