64 const std::size_t n = A.
rows();
65 if (A.
cols() != n)
throw InputError(
"stronglyconncomp: adjacency matrix is not square");
70 std::vector<std::vector<std::size_t>> pred(n), succ(n);
71 for (std::size_t i = 0; i < n; ++i)
72 for (std::size_t j = 0; j < n; ++j)
73 if (A(i, j) != zero) {
78 std::vector<std::size_t> index(n, 0), low(n, 0);
79 std::vector<char> onstack(n, 0);
80 std::vector<std::size_t> stack;
81 std::vector<std::vector<std::size_t>> comps;
82 std::size_t counter = 0;
86 std::vector<std::pair<std::size_t, std::size_t>> frames;
87 for (std::size_t s = 0; s < n; ++s) {
88 if (index[s] != 0)
continue;
89 frames.push_back(std::make_pair(s,
static_cast<std::size_t
>(0)));
95 while (!frames.empty()) {
96 const std::size_t u = frames.back().first;
97 std::size_t& p = frames.back().second;
98 if (p < pred[u].size()) {
99 const std::size_t v = pred[u][p];
107 frames.push_back(std::make_pair(v,
static_cast<std::size_t
>(0)));
108 }
else if (onstack[v]) {
109 if (index[v] < low[u]) low[u] = index[v];
114 if (low[u] == index[u]) {
115 std::vector<std::size_t> comp;
117 const std::size_t w = stack.back();
123 std::sort(comp.begin(), comp.end());
124 comps.push_back(comp);
127 if (!frames.empty()) {
128 const std::size_t parent = frames.back().first;
129 if (low[u] < low[parent]) low[parent] = low[u];
135 std::vector<std::size_t> order(comps.size());
136 std::iota(order.begin(), order.end(),
static_cast<std::size_t
>(0));
137 std::stable_sort(order.begin(), order.end(),
138 [&comps](std::size_t a, std::size_t b) {
139 return comps[a].size() > comps[b].size();
143 r.
members.resize(comps.size());
145 for (std::size_t k = 0; k < order.size(); ++k) {
146 r.
members[k] = comps[order[k]];
147 for (std::size_t v : r.
members[k]) r.
scc[v] = k + 1;
151 for (std::size_t k = 0; k < r.
members.size(); ++k) {
152 for (std::size_t v : r.
members[k]) {
153 for (std::size_t w : succ[v])
154 if (r.
scc[w] != k + 1) {