43 #ifndef UTIL_GRAPH_STRONGLY_CONNECTED_COMPONENTS_H_ 44 #define UTIL_GRAPH_STRONGLY_CONNECTED_COMPONENTS_H_ 72 template <
typename NodeIndex,
typename Graph,
typename SccOutput>
74 const Graph& graph, SccOutput* components);
82 template <
typename NodeIndex>
103 template <
typename NodeIndex,
typename Graph,
typename SccOutput>
108 SccOutput* components) {
111 scc_start_index_.clear();
112 node_index_.assign(num_nodes, 0);
113 node_to_process_.clear();
121 for (
NodeIndex base_node = 0; base_node < num_nodes; ++base_node) {
122 if (node_index_[base_node] != 0)
continue;
124 node_to_process_.push_back(base_node);
126 const NodeIndex node = node_to_process_.back();
130 scc_stack_.push_back(node);
131 current_scc_start = scc_stack_.size();
132 node_index_[node] = current_scc_start;
133 scc_start_index_.push_back(current_scc_start);
136 NodeIndex min_head_index = kSettledIndex;
139 if (head_index == 0) {
140 node_to_process_.push_back(
head);
143 min_head_index =
std::min(min_head_index, head_index);
151 while (current_scc_start > min_head_index) {
152 scc_start_index_.pop_back();
153 current_scc_start = scc_start_index_.back();
156 node_to_process_.pop_back();
157 if (current_scc_start ==
index) {
159 components->emplace_back(&scc_stack_[current_scc_start - 1],
160 &scc_stack_[0] + scc_stack_.size());
161 for (
int i = current_scc_start - 1; i < scc_stack_.size(); ++i) {
162 node_index_[scc_stack_[i]] = kSettledIndex;
164 scc_stack_.resize(current_scc_start - 1);
165 scc_start_index_.pop_back();
167 scc_start_index_.empty() ? 0 : scc_start_index_.back();
170 }
while (!node_to_process_.empty());
178 return node_index_[node] > 0 && node_index_[node] < kSettledIndex;
182 static constexpr
NodeIndex kSettledIndex =
188 std::vector<NodeIndex> scc_stack_;
194 std::vector<NodeIndex> scc_start_index_;
202 std::vector<NodeIndex> node_index_;
207 std::vector<NodeIndex> node_to_process_;
211 template <
typename NodeIndex,
typename Graph,
typename SccOutput>
214 SccOutput* components) {
219 #endif // UTIL_GRAPH_STRONGLY_CONNECTED_COMPONENTS_H_
void emplace_back(NodeIndex const *b, NodeIndex const *e)
void FindStronglyConnectedComponents(const NodeIndex num_nodes, const Graph &graph, SccOutput *components)
void FindStronglyConnectedComponents(const NodeIndex num_nodes, const Graph &graph, SccOutput *components)
#define DCHECK_EQ(val1, val2)
bool NodeIsInCurrentDfsPath(NodeIndex node) const