365 array<node> reachable(t.get_num_nodes_component(one_node));
367 auto it = reachable.
begin();
369 bfs.set_process_current([&](
const auto&,
node u) { *it++ = u; });
370 bfs.start_at(one_node);
372 const uint64_t size_tree = t.get_num_nodes_component(one_node);
381 assert(size_tree > 0);
385 if (size_tree == 1) {
387 assert(one_node == reachable[0]);
388 assert(start <= t.get_num_nodes());
390 if constexpr (make_arrangement) {
391 mla.assign(one_node, start);
404 const uint64_t n_0 = ord[0].
size;
405 const node t_0 = ord[0].v;
407 t.remove_edge(u, t_0,
false,
false);
411 (t, t_0, start, mla, c1);
415 (t, u, start + n_0, mla, c2);
419 t.add_edge(u, t_0,
false,
false);
423 const uint64_t uq = *q;
424 cost = std::numeric_limits<uint64_t>::max();
426 std::vector<edge> edges(2*uq + 1);
427 for (uint64_t i = 0; i <= 2*uq; ++i) {
428 edges[i] = {u, ord[i].v};
432 t.remove_edges(edges,
false,
false);
435 uint64_t size_rest_of_trees = 0;
436 for (uint64_t i = 2*uq + 1; i < ord.
size(); ++i) {
437 size_rest_of_trees += ord[i].
size;
440 for (uint64_t i = 0; i <= 2*uq; ++i) {
441 const auto Q_i =
get_Q(uq, i);
443 t.add_edge(u, ord[i].v,
false,
false);
447 uint64_t start_aux = start;
450 for (uint64_t j = 1; j <= uq; ++j) {
457 ord[pos_in_ord].v, start_aux,
460 start_aux += ord[pos_in_ord].
size;
470 start_aux += ord[i].
size + 1 + size_rest_of_trees;
471 for (uint64_t j = uq + 1; j <= 2*uq; ++j) {
474 uint64_t c_i_j_in = 0;
478 ord[pos_in_ord].v, start_aux,
481 start_aux += ord[pos_in_ord].
size;
489 for (uint64_t j = 1; j <= uq; ++j) {
490 subs += (uq - j + 1)*(ord[Q_i[j]].size + ord[Q_i[2*uq - j + 1]].size);
497 if constexpr (make_arrangement) {
498 mla = std::move(arr_aux);
502 assert(u != ord[i].v);
504 t.remove_edge(u, ord[i].v,
false,
false);
508 t.add_edges(edges,
false,
false);
516 const uint64_t n_0 = ord[0].
size;
517 const node t_0 = ord[0].v;
519 assert(one_node != t_0);
522 t.remove_edge(one_node, t_0,
false,
false);
529 (t, one_node, start, mla, c1);
532 (t, t_0, start + size_tree - ord[0].size, mla, c2);
536 (t, t_0, start, mla, c1);
539 (t, one_node, start + n_0, mla, c2);
542 cost = c1 + c2 + size_tree - ord[0].
size;
543 t.add_edge(one_node, t_0,
false,
false);
560 const uint64_t up = *p;
561 cost = std::numeric_limits<uint64_t>::max();
563 std::vector<edge> edges(2*up + 2);
564 for (uint64_t i = 0; i <= 2*up + 1; ++i) {
565 edges[i] = {one_node, ord[i].v};
569 t.remove_edges(edges,
false,
false);
572 uint64_t size_rest_of_trees= 0;
573 for (uint64_t i = 2*up + 2; i < ord.
size() ;++i) {
574 size_rest_of_trees += ord[i].
size;
577 for (uint64_t i = 0; i <= 2*up + 1; ++i) {
578 const auto P_i =
get_P(up, i);
579 t.add_edge(one_node, ord[i].v,
false,
false);
583 uint64_t start_aux = start;
587 for (uint64_t j = 1; j <= up; ++j) {
590 uint64_t c_i_j_in = 0;
594 ord[pos_in_ord].v, start_aux,
597 start_aux += ord[pos_in_ord].
size;
604 (t, one_node, start_aux, arr_aux, c_i_j);
606 start_aux += ord[i].
size + 1 + size_rest_of_trees;
610 for (uint64_t j = up + 1; j <= 2*up + 1; ++j) {
613 uint64_t c_i_j_in = 0;
617 ord[pos_in_ord].v, start_aux,
620 start_aux += ord[pos_in_ord].
size;
627 for (uint64_t j = 2*up + 1; j >= up + 1; --j) {
630 uint64_t c_i_j_in = 0;
634 ord[pos_in_ord].v, start_aux,
637 start_aux += ord[pos_in_ord].
size;
644 (t, one_node, start_aux, arr_aux, c_i_j);
646 start_aux += ord[i].
size + 1 + size_rest_of_trees;
650 for (uint64_t j = up; j >= 1; --j) {
653 uint64_t c_i_j_in = 0;
657 ord[pos_in_ord].v, start_aux,
660 start_aux += ord[pos_in_ord].
size;
666 c_i += size_tree*(up + 1);
667 c_i -= (up + 1)*ord[P_i[P_i.size() - 1]].
size;
670 for (uint64_t j = 1; j <= up; ++j) {
671 subs += (up - j + 1)*(ord[P_i[j]].size + ord[P_i[2*up - j + 1]].size);
681 assert(one_node != ord[i].v);
683 t.remove_edge(one_node, ord[i].v,
false,
false);
687 t.add_edges(edges,
false,
false);