109 SccOutput* components) {
112 scc_start_index_.clear();
113 node_index_.assign(num_nodes, 0);
114 node_to_process_.clear();
117 absl::Span<NodeIndex> node_index = absl::MakeSpan(node_index_);
121 NodeIndex current_scc_start = 0;
125 for (NodeIndex base_node = 0; base_node < num_nodes; ++base_node) {
126 if (node_index[base_node] != 0)
continue;
127 DCHECK_EQ(0, node_to_process_.size());
128 node_to_process_.push_back(base_node);
130 const NodeIndex node = node_to_process_.back();
131 const NodeIndex
index = node_index[node];
134 scc_stack_.push_back(node);
135 current_scc_start = scc_stack_.size();
136 node_index[node] = current_scc_start;
137 scc_start_index_.push_back(current_scc_start);
140 NodeIndex min_head_index = kSettledIndex;
141 for (
const NodeIndex
head :
graph[node]) {
144 node_to_process_.push_back(
head);
147 min_head_index = std::min(min_head_index,
head_index);
155 while (current_scc_start > min_head_index) {
156 scc_start_index_.pop_back();
157 current_scc_start = scc_start_index_.back();
160 node_to_process_.pop_back();
161 if (current_scc_start ==
index) {
163 components->emplace_back(&scc_stack_[current_scc_start - 1],
164 &scc_stack_[0] + scc_stack_.size());
165 for (
int i = current_scc_start - 1; i < scc_stack_.size(); ++i) {
166 node_index[scc_stack_[i]] = kSettledIndex;
168 scc_stack_.resize(current_scc_start - 1);
169 scc_start_index_.pop_back();
171 scc_start_index_.empty() ? 0 : scc_start_index_.back();
174 }
while (!node_to_process_.empty());