Files
reachability-algorithms/algorithm/tarjan.h
2022-05-06 12:25:04 +03:00

74 lines
1.4 KiB
C++

#ifndef TARJAN_H_
#define TARJAN_H_
#include "graph/graph.h"
using namespace graph;
#include <stack>
#include <iostream>
#include <ranges>
#include <iterator>
#include <algorithm>
namespace algorithm {
template<typename T>
class Tarjan {
public:
Tarjan(Graph<T> G) : G(G) {}
void findSCC();
void strongConnect(Vertex<T>& v);
std::uint16_t index = 0;
std::stack<Vertex<T>> S;
private:
Graph<T> G;
};
template<typename T>
void Tarjan<T>::strongConnect(Vertex<T>& v) {
v.index, v.lowlink = index++;
v.onStack = true;
S.push(v);
for (auto& w : v.edges) {
if (w.index == -1) {
// successor w has not yet been visited, recurse on it
strongConnect(w);
v.lowlink = std::min(v.lowlink, w.lowlink);
} else if (w.onStack) {
// successor w is in stack S and hence in the current SCC
// if w is not on stack, then (v, w) is an edge pointing to an SCC
// already found and must be ignored
v.lowlink = std::min(v.lowlink, w.index);
}
}
// if v is a root node, pop the stack and generate an SCC
if (v.lowlink = v.index) {
// start a new SCC
Vertex<T> w;
do {
w = S.top();
S.pop();
// add w to current SCC
} while (w != v);
}
}
template<typename T>
void Tarjan<T>::findSCC() {
for (auto& vertex : G.vertices) {
if (vertex.index == -1) {
strongConnect(vertex);
}
}
}
} // namespace algorithm
#endif