@@ -426,39 +426,40 @@ OutIt dijkstra(const std::size_t n, InIt first, InIt last, OutIt dest, const std
426426 return dest;
427427}
428428
429- template <class InIt , class OutIt , class Pr1 = EdgeLess, class Pr2 = EdgeLess>
430- OutIt boruvka (const std::size_t n, InIt first, InIt last, OutIt dest, Pr1 preferred = Pr1{}, Pr2 tie_break = Pr2{}) {
429+ template <class InIt , class OutIt , class Pred = EdgeLess>
430+ OutIt boruvka (const std::size_t n, InIt first, InIt last, OutIt dest, Pred pred = Pred{}) {
431+ using edge_ptr = decltype (&*first);
432+
431433 DisjointSet<std::size_t > ds (n);
432- std::vector<std::size_t > cheapest (n, std::numeric_limits<std::size_t >::max ());
433- std::vector<std::size_t > cheapest_edge (n, std::numeric_limits<std::size_t >::max ());
434+ std::vector<edge_ptr> cheapest (n);
434435
435- std::size_t mst_size = 0 ;
436- while (mst_size < n - 1 ) {
437- for (std::size_t i = 0 ; i < n; ++i) {
438- cheapest[i] = std::numeric_limits<std::size_t >::max ();
439- cheapest_edge[i] = std::numeric_limits<std::size_t >::max ();
440- }
436+ for (std::size_t components = n; components > 1 ;) {
437+ std::fill (cheapest.begin (), cheapest.end (), nullptr );
441438
442439 for (auto it = first; it != last; ++it) {
443440 auto set1 = ds.find (it->from );
444441 auto set2 = ds.find (it->to );
445-
446- if (set1 == set2 ) {
447- continue ;
448- }
449-
450- if (preferred (*it, cheapest[set1]) || ( tie_break ( *it, cheapest[set1]) && it-> weight == cheapest[set1 ])) {
451- cheapest[set1] = it-> weight ;
452- cheapest_edge[set1] = it-> to ;
442+ if (set1 != set2) {
443+ if (!cheapest[ set1] || pred (*it, *cheapest[set1]) ) {
444+ cheapest[set1] = &*it ;
445+ }
446+
447+ if (! cheapest[set2] || pred ( *it, * cheapest[set2 ])) {
448+ cheapest[set2] = &*it ;
449+ }
453450 }
454451 }
455452
456453 for (std::size_t i = 0 ; i < n; ++i) {
457- if (cheapest[i] != std::numeric_limits<std::size_t >::max ()) {
458- ds.union_rank (cheapest_edge[i], i);
459- *dest = Edge{cheapest_edge[i], i, cheapest[i]};
460- ++mst_size;
461- ++dest;
454+ if (!cheapest[i]) {
455+ continue ;
456+ }
457+
458+ auto set1 = ds.find (cheapest[i]->from ), set2 = ds.find (cheapest[i]->to );
459+ if (set1 != set2) {
460+ ds.union_rank (set1, set2);
461+ *dest++ = *cheapest[i];
462+ --components;
462463 }
463464 }
464465 }
0 commit comments