Implementation

using g = unordered_map<Node, unordered_set<Node>>;

vector<vector<Node>> strongely_connected_components()
{
    stack<Node> finished_nodes;

    // first dfs pass
    for (auto &i : graph) {
        if (i.first.state == UnVisited) {
            SCC_pass1_rec(const_cast<Node&>(i.first), finished_nodes);
        }
    }

    resetStates();
    g rev_graph = transpose_graph();

    vector<vector<Node>> completed_sets;
    vector<Node> v_temp;

    // second dfs pass
    while (!finished_nodes.empty()) {
        Node temp_n = finished_nodes.top();
        const Node *the_r_n = &rev_graph.find(temp_n)->first;
        finished_nodes.pop();

        if (the_r_n->state == UnVisited) {
            SSC_pass2_rec(rev_graph, temp_n, v_temp);
            completed_sets.push_back(v_temp);
            v_temp.clear();
        }
    }

    return completed_sets;
}

void SCC_pass1_rec(Node &curNode, stack<Node> &fnshd_nodes)
{
    const_cast<Node&>(graph.find(curNode)->first).state = Visited;
    unordered_set<Node> AdjNodes = findAdj(curNode);

    for (auto i : AdjNodes) {
        const Node *the_r_n = &graph.find(i)->first;
        if (the_r_n->state == UnVisited) {
            SCC_pass1_rec(i, fnshd_nodes);
        }
    }
    fnshd_nodes.push(curNode);
}

void SSC_pass2_rec(g &rev_g, Node &curNode, vector<Node> &temp_v)
{
    const_cast<Node&>(rev_g.find(curNode)->first).state = Visited;
    unordered_set<Node> AdjNodes = rev_g.find(curNode)->second;

    for (auto i : AdjNodes) {
        const Node *the_r_n = &rev_g.find(i)->first;
        if (the_r_n->state == UnVisited) {
            SSC_pass2_rec(rev_g, i, temp_v);
        }
    }
    temp_v.push_back(curNode);
}

g transpose_graph()
{
    g rev_g;
    rev_g.reserve(graph.size());

    for (auto i : graph) {
        for (auto j : i.second) {
            if (rev_g.find(j) == rev_g.end()) {
                rev_g.insert({j, unordered_set<Node>()});
                rev_g.find(j)->second.insert(i.first);
            }
            else rev_g.find(j)->second.insert(i.first);

        }
    }

    return rev_g;
}

InFile

11
A : B
B : C, D
C : A
D : E
E : F
F : D
G : F, H
H : I
I : J
J : G, K
K :

Last updated