6 #ifndef JLM_UTIL_TARJANSCC_HPP
7 #define JLM_UTIL_TARJANSCC_HPP
50 template<
typename NodeType,
typename UnificationRootFunctor,
typename SuccessorFunctor>
54 UnificationRootFunctor unificationRoot,
55 SuccessorFunctor & successors,
56 std::vector<NodeType> & sccIndex,
57 std::vector<NodeType> & reverseTopologicalOrder)
59 NodeType sccsFinished = 0;
62 sccIndex.resize(numNodes);
64 reverseTopologicalOrder.resize(0);
67 const NodeType NOT_VISITED = std::numeric_limits<NodeType>::max();
68 const NodeType SCC_FINISHED = NOT_VISITED - 1;
72 std::vector<NodeType> order(numNodes, NOT_VISITED);
73 NodeType nextOrder = 0;
75 std::vector<NodeType> lowLink(numNodes);
79 std::stack<NodeType> dfsStack;
81 std::stack<NodeType> sccStack;
84 for (NodeType startNode = 0; startNode < numNodes; startNode++)
87 if (unificationRoot(startNode) != startNode)
91 if (order[startNode] != NOT_VISITED)
94 dfsStack.push(startNode);
95 while (!dfsStack.empty())
97 auto node = dfsStack.top();
99 if (order[node] == NOT_VISITED)
102 order[node] = nextOrder++;
103 lowLink[node] = order[node];
105 for (
auto next : successors(node))
107 next = unificationRoot(next);
110 if (order[next] == NOT_VISITED)
114 else if (order[node] == SCC_FINISHED)
122 for (
auto next : successors(node))
124 next = unificationRoot(next);
127 if (order[next] == SCC_FINISHED)
129 lowLink[node] = std::min(lowLink[node], lowLink[next]);
133 if (lowLink[node] == order[node])
135 const auto thisSccIndex = sccsFinished;
139 auto top = sccStack.top();
141 order[top] = SCC_FINISHED;
142 sccIndex[top] = thisSccIndex;
143 reverseTopologicalOrder.push_back(top);
175 template<
typename NodeType,
typename SuccessorFunctor>
179 SuccessorFunctor & successors,
180 std::vector<NodeType> & sccIndex,
181 std::vector<NodeType> & reverseTopologicalOrder)
183 const auto identity = [](NodeType n)
189 reverseTopologicalOrder.reserve(numNodes);
196 reverseTopologicalOrder);
NodeType FindStronglyConnectedComponents(NodeType numNodes, UnificationRootFunctor unificationRoot, SuccessorFunctor &successors, std::vector< NodeType > &sccIndex, std::vector< NodeType > &reverseTopologicalOrder)