25 # ifndef DSGGRAPHALGORITHMS_H 26 # define DSGGRAPHALGORITHMS_H 37 template <
class GT,
class Op>
40 template <
class GT,
class Op>
43 template <
class GT,
class Op>
46 depth_first_traverse_prefix<GT, Op>(g, op);
49 template <
class GT,
class Op>
52 template <
class GT,
class Op>
55 template <
class GT,
class Op>
58 depth_first_traverse_sufix<GT, Op>(g, op);
61 template <
class GT,
class Op>
64 depth_first_traverse_prefix<GT, Op>(g, op);
67 template <
class GT,
class Op>
70 depth_first_traverse<GT, Op>(g, op);
132 std::tuple<GT, SLList<Arc<GT> *>>
151 template <
class GT,
class Op>
154 template <
class GT,
class Op>
157 breadth_first_traverse<GT, Op>(g, p, op);
160 template <
class GT,
class Op>
163 breadth_first_traverse<GT, Op>(g, g.get_first_node(), op);
166 template <
class GT,
class Op>
169 breadth_first_traverse<GT, Op>(g, op);
181 template <
class GT,
class Op>
190 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
205 template <
class GT,
class Op>
213 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
244 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
271 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
299 if (g.get_num_arcs() >= g.get_num_nodes())
302 return g.exists_node([&g] (
Node<GT> * p)
319 if (g.get_num_arcs() >= g.get_num_nodes())
322 return g.all_nodes([&g] (
Node<GT> * p)
328 template <
class GT,
class Op>
333 for (
NodeIt<GT> it(g); it.has_current(); it.next())
344 template <
class GT,
class Op>
349 for (
NodeIt<GT> it(g); it.has_current(); it.next())
381 if (not g.is_digraph())
382 throw std::domain_error(
"Argument must be a directed graph");
384 g.reset_node_cookies();
388 g.for_each_arc([&i] (
auto a)
390 auto s = a->get_src_node();
391 auto t = a->get_tgt_node();
392 auto sp = mapped_node<GT>(s);
396 sp = i.insert_node(s->get_info());
397 map_nodes<GT>(s, sp);
400 auto tp = mapped_node<GT>(t);
404 tp = i.insert_node(t->get_info());
405 map_nodes<GT>(t, tp);
408 auto ap = i.insert_arc(tp, sp, a->get_info());
424 Node<GT> * pp = t.insert_node(p->get_info());
425 map_nodes<GT>(p, pp);
427 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
429 Arc<GT> * a = it.get_current();
442 Arc<GT> * aa = t.insert_arc(pp, qq, a->get_info());
451 throw std::domain_error(
"Argument must be an undirected graph");
458 g.for_each_node([&g, &ret] (
Node<GT> * p)
483 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
485 Arc<GT> * a = it.get_current();
502 throw std::domain_error(
"Argument must be an undirected graph");
509 g.for_each_node([&g, &ret] (
Node<GT> * p)
528 low<GT>(p) = df<GT>(p) = cdf++;
532 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
534 Arc<GT> * arc = it.get_current();
544 low<GT>(p) = std::min(low<GT>(p), df<GT>(q));
556 low<GT>(p) = std::min(low<GT>(p), low<GT>(q));
558 is_cut = low<GT>(q) >= df<GT>(p) and df<GT>(q) != 0;
580 nat_t call_counter = 0;
583 Node<GT> * start = g.get_first_node();
585 df<GT>(start) = current_df++;
589 for (
AdArcIt<GT> it(g, start); it.has_current(); it.next())
596 Arc<GT> * a = it.get_current();
607 if (call_counter > 1)
620 if (p->counter() > 0)
625 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
627 Arc<GT> * a = it.get_current();
629 if (a->counter() > 0)
646 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
648 Arc<GT> * a = it.get_current();
660 if (q->counter() > 0)
676 l.for_each([&g, &color] (
Node<GT> * curr)
690 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
692 Arc<GT> * a = it.get_current();
703 qp = mapped_node<GT>(q);
706 qp = t.insert_node(q->get_info());
707 map_nodes<GT>(q, qp);
711 Arc<GT> * ap = t.insert_arc(pp, qp, a->get_info());
723 for (
NodeIt<GT> it(g); it.has_current(); it.next())
731 Node<GT> * q = t.insert_node(p->get_info());
735 list.
append(std::move(t));
742 std::tuple<GT, SLList<Arc<GT> *>>
750 Node<GT> * q = cut_graph.insert_node(p->get_info());
755 g.for_each_arc([&] (
Arc<GT> * a)
757 if (a->counter() == -1)
766 auto p = mapped_node<GT>(a->get_src_node());
767 auto q = mapped_node<GT>(a->get_tgt_node());
769 cut_graph.insert_arc(p, q, a->get_info());
773 return std::make_tuple(std::move(cut_graph), std::move(cross_arcs));
785 return std::make_tuple(std::move(subgraphs), std::move(std::get<0>(t)),
786 std::move(std::get<1>(t)));
796 Node<GT> * pp = sg.insert_node(p->get_info());
797 map_nodes<GT>(p, pp);
802 for (
AdArcIt<GT> it(inv_g, p); it.has_current(); it.next())
804 Arc<GT> * a = it.get_current();
815 if (p->counter() != q->counter())
818 Arc<GT> * ap = sg.insert_arc(qp, pp, a->get_info());
827 if (not g.is_digraph())
828 throw std::domain_error(
"Argument must be a directed graph");
843 nat_t num_component = 1;
845 for (i = g.get_num_nodes(); i > 0; --i)
863 if (not g.is_digraph())
864 throw std::domain_error(
"Argument must be a directed graph");
876 template <
class GT,
class Op>
890 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
924 g.reset_node_cookies();
932 while (not queue.
is_empty() and (ptr = queue.
get()) != end)
934 for (
AdArcIt<GT> it(g, ptr); it.has_current(); it.next())
954 if (end->cookie() ==
nullptr)
962 aux =
reinterpret_cast<Node<GT> *
>(aux->cookie());
973 if (not g.is_digraph())
974 throw std::domain_error(
"Argument must be a directed graph");
976 g.reset_node_counter();
978 g.for_each_arc([] (
Arc<GT> * a)
980 ++a->get_tgt_node()->counter();
985 g.for_each_node([&queue] (
Node<GT> * p)
987 if (p->counter() == 0)
999 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
1003 if (--q->counter() == 0)
1014 if (not g.is_digraph())
1015 throw std::domain_error(
"Argument must be a directed graph");
1017 g.reset_node_counter();
1019 g.for_each_arc([] (
Arc<GT> * a)
1021 ++a->get_tgt_node()->counter();
1026 g.for_each_node([&queue] (
Node<GT> * p)
1028 if (p->counter() == 0)
1046 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
1050 if (--q->counter() == 0)
1055 queue = std::move(aqueue);
1065 using Type =
typename GT::ArcInfoType;
1068 static constexpr
Type MAX = std::numeric_limits<Type>::max();
1072 return a.get_info();
1077 return a->get_info();
1081 template <
class GT,
class Distance,
class Cmp>
1084 Distance & distance;
1089 : distance(d), cmp(_cmp)
1095 : distance(d), cmp(_cmp)
1102 return cmp(distance(a), distance(b));
1108 class Cmp = std::less<typename Distance::Type>>
1117 using DistanceType =
typename Distance::Type;
1121 Distance & distance;
1126 : distance(_distance), cmp(distance, _cmp)
1132 Cmp && _cmp = Cmp())
1133 : distance(_distance),
1134 cmp(std::forward<Distance>(_distance), std::forward<Cmp>(_cmp))
1139 GT build_min_spanning_tree(
const GT &);
1143 GT tree = build_min_spanning_tree(g);
1147 tree.for_each_node([] (
Node<GT> * t_node)
1149 Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1153 tree.for_each_arc([](
Arc<GT> * t_arc)
1155 Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1161 template <
class GT,
class Distance,
class DistanceCmp>
1167 const_cast<GT &
>(g).
template sort_arcs(cmp);
1173 for (
ArcIt<GT> it(g); it.has_current() and
1174 tree.get_num_arcs() < g.get_num_nodes() - 1; it.next())
1177 Node<GT> * gs = ga->get_src_node();
1178 Node<GT> * gt = ga->get_tgt_node();
1180 Node<GT> * ts_ptr = mapped_node<GT>(gs);
1182 if (ts_ptr ==
nullptr)
1185 ts_ptr = tree.insert_node(gs->get_info());
1186 map_nodes<GT>(gs, ts_ptr);
1189 Node<GT> * tt_ptr = mapped_node<GT>(gt);
1191 if (tt_ptr ==
nullptr)
1194 tt_ptr = tree.insert_node(gt->get_info());
1195 map_nodes<GT>(gt, tt_ptr);
1198 if (nodes_rel.are_connected(ts_ptr, tt_ptr))
1201 nodes_rel.
join(ts_ptr, tt_ptr);
1203 Arc<GT> * ta = tree.insert_arc(ts_ptr, tt_ptr, ga->get_info());
1205 map_arcs<GT>(ga, ta);
1211 template <
class GT,
class Distance,
class Cmp>
1214 Distance & distance;
1219 : distance(_distance), cmp(_cmp)
1223 ArcHeapCmp(Distance && _distance = Distance(), Cmp && _cmp = Cmp())
1224 : distance(_distance), cmp(_cmp)
1231 return cmp(distance(a), distance(b));
1237 class Cmp = std::less<typename Distance::Type>>
1244 using BaseHeap::BaseHeap;
1251 Arc<GT> *** result = tgt_nodes.
search(t);
1253 if (result ==
nullptr)
1255 tgt_nodes[t] =
const_cast<Arc<GT> **
>(&BaseHeap::insert(a));
1259 Arc<GT> ** ap = *result;
1261 if (BaseHeap::get_cmp()(*ap, a))
1264 BaseHeap::remove(*ap);
1265 tgt_nodes[t] =
const_cast<Arc<GT> **
>(&BaseHeap::insert(a));
1270 Arc<GT> * arc_ptr = BaseHeap::top();
1271 Node<GT> * tgt_ptr = arc_ptr->get_src_node();
1272 Arc<GT> *** result = tgt_nodes.
search(tgt_ptr);
1274 if (result ==
nullptr or **result != arc_ptr)
1275 result = tgt_nodes.
search(tgt_ptr = arc_ptr->get_tgt_node());
1277 assert(**result == arc_ptr);
1280 tgt_nodes.
remove(tgt_ptr);
1288 class Cmp = std::less<typename Distance::Type>>
1296 Distance & distance;
1299 using DistanceType =
typename Distance::Type;
1304 Prim(Distance & _distance, Cmp & _cmp)
1305 : distance(_distance), cmp(_cmp)
1310 Prim(Distance && _distance = Distance(), Cmp && _cmp = Cmp())
1311 : distance(_distance), cmp(_cmp)
1316 GT build_min_spanning_tree(
const GT &,
Node<GT> *);
1320 return build_min_spanning_tree(g, g.get_first_node());
1325 GT tree = build_min_spanning_tree(g, start);
1329 tree.for_each_node([] (
Node<GT> * t_node)
1331 Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1333 ptr_g_node->cookie() =
nullptr;
1336 tree.for_each_arc([](
Arc<GT> * t_arc)
1338 Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1340 ptr_g_arc->cookie() =
nullptr;
1346 paint_min_spanning_tree(g, g.get_first_node());
1350 template <
class GT,
class Distance,
class Cmp>
1357 Node<GT> * t_start = tree.insert_node(start->get_info());
1358 map_nodes<GT>(start, t_start);
1364 for (
AdArcIt<GT> it(g, start); it.has_current(); it.next())
1367 Node<GT> * t = a->get_connected_node(start);
1371 while (not arc_heap.
is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1375 if (a->is_visited(TAG))
1380 Node<GT> * p = a->get_src_node()->is_visited(TAG) ?
1381 a->get_tgt_node() : a->get_src_node();
1383 if (p->is_visited(TAG))
1388 Node<GT> * pp = tree.insert_node(p->get_info());
1389 map_nodes<GT>(p, pp);
1391 Node<GT> * ts = mapped_node<GT>(a->get_src_node());
1392 Node<GT> * tt = mapped_node<GT>(a->get_tgt_node());
1393 Arc<GT> * ap = tree.insert_arc(ts, tt, a->get_info());
1395 map_arcs<GT>(a, ap);
1397 for (
AdArcIt<GT> it(g, p); it.has_current(); it.next())
1400 Node<GT> * pt = pa->get_connected_node(p);
1410 class Cmp = std::less<typename Distance::Type>,
1411 class Plus = std::plus<typename Distance::Type>>
1419 Distance & distance;
1423 using DistanceType =
typename Distance::Type;
1432 Dijkstra(Distance & _distance, Cmp & _cmp, Plus & _plus)
1433 : distance(_distance), cmp(_cmp), plus(_plus)
1439 Cmp && _cmp = Cmp(), Plus && _plus = Plus())
1440 : distance(_distance), cmp(_cmp), plus(_plus)
1445 GT build_min_path_tree(
const GT &,
Node<GT> *);
1449 GT tree = build_min_path_tree(g, start);
1453 tree.for_each_node([] (
Node<GT> * t_node)
1455 Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1457 ptr_g_node->cookie() =
nullptr;
1460 tree.for_each_arc([](
Arc<GT> * t_arc)
1462 Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1464 ptr_g_arc->cookie() =
nullptr;
1470 GT tree = build_partial_min_path_tree(g, start, end);
1472 Node<GT> * t_start = mapped_node<GT>(start);
1473 Node<GT> * t_end = mapped_node<GT>(end);
1478 if (t_path.is_empty())
1485 if (ptr_arc ==
nullptr)
1488 Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
1497 Path<GT> path = search_min_path(g, start, end);
1505 if (ptr_arc !=
nullptr)
1511 template <
class GT,
class Distance,
class Cmp,
class Plus>
1516 allocate_node_info<GT, Distance>(g);
1517 allocate_arc_info<GT, Distance>(g);
1523 TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1524 TREE_NODE<GT, Distance>(start)->cookie() = start;
1530 for (
AdArcIt<GT> it(g, start); it.has_current(); it.next())
1533 POT<GT, Distance>(arc) = distance(arc);
1535 put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1538 while (not heap.
is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1540 Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1541 Node<GT> * g_src = g_arc->get_src_node();
1542 Node<GT> * g_tgt = g_arc->get_tgt_node();
1544 if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1547 Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1549 Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1551 TREE_NODE<GT, Distance>(new_node) = t_tgt;
1553 new_node->visit(TAG);
1555 Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1556 TREE_NODE<GT, Distance>(g_tgt),
1559 TREE_ARC<GT, Distance>(g_arc) = t_arc;
1561 if (new_node == end)
1564 ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1566 const DistanceType & acc = ACC<GT, Distance>(new_node);
1568 for (
AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1572 if (arc->is_visited(TAG))
1577 Node<GT> * tgt = it.get_tgt_node();
1579 if (tgt->is_visited(TAG))
1582 POT<GT, Distance>(arc) = plus(acc, distance(arc));
1584 put_in_heap<GT, Distance>(arc, tgt, heap);
1589 destroy_node_info<GT, Distance>(g);
1590 destroy_arc_info<GT, Distance>(g);
1595 template <
class GT,
class Distance,
class Cmp,
class Plus>
1600 allocate_node_info<GT, Distance>(g);
1601 allocate_arc_info<GT, Distance>(g);
1607 TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1608 TREE_NODE<GT, Distance>(start)->cookie() = start;
1614 for (
AdArcIt<GT> it(g, start); it.has_current(); it.next())
1618 POT<GT, Distance>(arc) = distance(arc);
1620 put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1623 while (not heap.
is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1625 Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1626 Node<GT> * g_src = g_arc->get_src_node();
1627 Node<GT> * g_tgt = g_arc->get_tgt_node();
1629 if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1632 Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1634 Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1636 TREE_NODE<GT, Distance>(new_node) = t_tgt;
1638 new_node->visit(TAG);
1640 Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1641 TREE_NODE<GT, Distance>(g_tgt),
1644 TREE_ARC<GT, Distance>(g_arc) = t_arc;
1646 ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1648 const DistanceType & acc = ACC<GT, Distance>(new_node);
1650 for (
AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1654 if (arc->is_visited(TAG))
1659 Node<GT> * tgt = it.get_tgt_node();
1661 if (tgt->is_visited(TAG))
1664 POT<GT, Distance>(arc) = plus(acc, distance(arc));
1666 put_in_heap<GT, Distance>(arc, tgt, heap);
1671 destroy_node_info<GT, Distance>(g);
1672 destroy_arc_info<GT, Distance>(g);
1677 template <
class GT,
class Distance>
1690 class Cmp = std::less<typename Distance::Type>,
1691 class Plus = std::plus<typename Distance::Type>>
1699 Distance & distance;
1700 Heuristic & heuristic;
1704 using DistanceType =
typename Distance::Type;
1713 Astar(Distance & _distance, Heuristic & _heuristic,
1714 Cmp & _cmp, Plus & _plus)
1715 : distance(_distance), heuristic(_heuristic), cmp(_cmp),
1721 Astar(Distance && _distance = Distance(),
1722 Heuristic && _heuristic = Heuristic(), Cmp && _cmp = Cmp(),
1723 Plus && _plus = Plus())
1724 : distance(_distance), heuristic(_heuristic), cmp(_cmp),
1732 GT tree = build_partial_min_path_tree(g, start, end);
1734 Node<GT> * t_start = mapped_node<GT>(start);
1735 Node<GT> * t_end = mapped_node<GT>(end);
1740 if (t_path.is_empty())
1747 if (ptr_arc ==
nullptr)
1750 Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
1759 Path<GT> path = search_min_path(g, start, end);
1767 if (ptr_arc !=
nullptr)
1773 template <
class GT,
class Distance,
class Heuristic,
class Cmp,
class Plus>
1778 allocate_node_info<GT, Distance>(g);
1779 allocate_arc_info<GT, Distance>(g);
1785 TREE_NODE<GT, Distance>(start) = tree.insert_node(start->get_info());
1786 TREE_NODE<GT, Distance>(start)->cookie() = start;
1792 for (
AdArcIt<GT> it(g, start); it.has_current(); it.next())
1795 POT<GT, Distance>(arc) = plus(distance(arc),
1796 heuristic(it.get_tgt_node(), end));
1798 put_in_heap<GT, Distance>(arc, arc->get_connected_node(start), heap);
1801 while (not heap.
is_empty() and tree.get_num_nodes() < g.get_num_nodes())
1803 Arc<GT> * g_arc = get_from_heap<GT, Distance>(heap);
1804 Node<GT> * g_src = g_arc->get_src_node();
1805 Node<GT> * g_tgt = g_arc->get_tgt_node();
1807 if (g_src->is_visited(TAG) and g_tgt->is_visited(TAG))
1810 Node<GT> * new_node = g_src->is_visited(TAG) ? g_tgt : g_src;
1812 Node<GT> * t_tgt = tree.insert_node(new_node->get_info());
1814 TREE_NODE<GT, Distance>(new_node) = t_tgt;
1816 new_node->visit(TAG);
1818 Arc<GT> * t_arc = tree.insert_arc(TREE_NODE<GT, Distance>(g_src),
1819 TREE_NODE<GT, Distance>(g_tgt),
1822 TREE_ARC<GT, Distance>(g_arc) = t_arc;
1824 if (new_node == end)
1827 ACC<GT, Distance>(new_node) = POT<GT, Distance>(g_arc);
1829 const DistanceType & acc = ACC<GT, Distance>(new_node);
1831 for (
AdArcIt<GT> it(g, new_node); it.has_current(); it.next())
1835 if (arc->is_visited(TAG))
1840 Node<GT> * tgt = it.get_tgt_node();
1842 if (tgt->is_visited(TAG))
1845 POT<GT, Distance>(arc) = plus(plus(acc, distance(arc)),
1846 heuristic(it.get_tgt_node(), end));
1848 put_in_heap<GT, Distance>(arc, tgt, heap);
1853 destroy_node_info<GT, Distance>(g);
1854 destroy_arc_info<GT, Distance>(g);
1861 class Cmp = std::less<typename Distance::Type>,
1862 class Plus = std::plus<typename Distance::Type>>
1868 Distance & distance;
1875 typename Distance::Type accum;
1878 static BFNodeInfo *& BFNI(
Node<GT> * p)
1880 return (BFNodeInfo *&) p->cookie();
1883 static typename Distance::Type &
ACC(
Node<GT> * p)
1885 return BFNI(p)->accum;
1890 return BFNI(p)->idx;
1893 static void init_node_info(
const GT & g,
1903 BFNI(p) =
new BFNodeInfo;
1905 ACC(p) = Distance::MAX;
1925 if (
ACC(s) == Distance::MAX)
1928 typename Distance::Type sum = plus(
ACC(s), distance(a));
1930 if (cmp(sum,
ACC(t)))
1932 const nat_t & i = IDX(t);
1947 : distance(_distance), cmp(_cmp), plus(_plus)
1953 Plus && _plus = Plus())
1954 : distance(_distance), cmp(_cmp), plus(_plus)
1959 std::tuple<bool, GT> build_min_path_tree(
const GT &,
Node<GT> *);
1963 auto t = build_min_path_tree(g, start);
1965 if (not std::get<0>(t))
1970 const GT & tree = std::get<1>(t);
1972 tree.for_each_node([] (
Node<GT> * t_node)
1974 Node<GT> * ptr_g_node = mapped_node<GT>(t_node);
1976 ptr_g_node->cookie() =
nullptr;
1979 tree.for_each_arc([](
Arc<GT> * t_arc)
1981 Arc<GT> * ptr_g_arc = mapped_arc<GT>(t_arc);
1983 ptr_g_arc->cookie() =
nullptr;
1991 auto t = build_min_path_tree(g, start, end);
1993 if (not std::get<0>(t))
1994 return make_tuple(
false,
Path<GT>());
1996 const GT & tree = std::get<1>(t);
1998 Node<GT> * t_start = mapped_node<GT>(start);
1999 Node<GT> * t_end = mapped_node<GT>(end);
2004 if (t_path.is_empty())
2011 if (ptr_arc ==
nullptr)
2014 Arc<GT> * arc = mapped_arc<GT>(ptr_arc);
2018 return make_tuple(
true, path);
2023 auto t = search_min_path(g, start, end);
2025 if (not std::get<0>(t))
2036 if (ptr_arc !=
nullptr)
2045 template <
class GT,
class Distance,
class Cmp,
class Plus>
2050 nat_t n = g.get_num_nodes() - 1;
2052 bool had_relaxation =
true;
2056 for (i = 0; had_relaxation and i < n; ++i)
2058 had_relaxation =
false;
2060 g.for_each_arc([&] (
Arc<GT> * a)
2062 if (relax(a, pred, arcs))
2063 had_relaxation =
true;
2070 had_relaxation =
false;
2072 g.for_each_arc([&] (
Arc<GT> * a)
2074 if (relax(a, pred, arcs))
2075 had_relaxation =
true;
2078 return not had_relaxation;
2081 template <
class GT,
class Distance,
class Cmp,
class Plus>
2085 if (not g.is_digraph())
2086 throw std::domain_error(
"Argument must be a directed graph");
2091 init_node_info(g, pred, arcs);
2094 bool result = generic_algorithm(g, pred, arcs);
2099 return std::make_tuple(
false, GT());
2103 for (
nat_t i = 0; i < arcs.size(); ++i)
2112 Node<GT> * st = mapped_node<GT>(s);
2116 st = tree.insert_node(s->get_info());
2117 map_nodes<GT>(s, st);
2122 Node<GT> * tt = mapped_node<GT>(t);
2126 tt = tree.insert_node(t->get_info());
2127 map_nodes<GT>(t, tt);
2130 Arc<GT> * at = tree.insert_arc(st, tt, a->get_info());
2131 map_arcs<GT>(a, at);
2134 return std::make_tuple(
true, std::move(tree));
2149 static constexpr
real_t SQ_TWO = 1.414213562;
2155 return n * n * std::log10(n);
2158 MGraph build_mgraph(
const GT & g)
2169 map_nodes<GT, MGraph>(p, mp);
2172 g.for_each_arc([&] (
Arc<GT> * a)
2177 MNode * mp = mapped_node<GT, MGraph>(p);
2178 MNode * mq = mapped_node<GT, MGraph>(q);
2193 void contract_arc(
MGraph &, MNode *, MNode *, MNode *,
ArcSet &);
2200 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2201 compute_min_cut(
MGraph & mg)
2203 return compute_min_cut(mg, num_iterations_hint(mg.
get_num_nodes()));
2206 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2207 compute_min_cut_fast_rec(
MGraph &);
2222 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2225 if (g.get_num_arcs() == 0)
2226 throw std::domain_error(
"Graph has not arcs");
2228 MGraph mg = build_mgraph(g);
2229 return compute_min_cut(mg, num_it);
2232 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2235 return compute_min_cut(g, num_iterations_hint(g.get_num_nodes()));
2238 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2241 MGraph mg = build_mgraph(g);
2242 return compute_min_cut_fast_rec(mg);
2245 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2248 return compute_min_cut_fast(g);
2254 MNode * r,
ArcSet & arcs)
2258 MArc * a = it.get_current();
2259 MNode * t = it.get_tgt_node();
2266 MArc * aa = mg.
insert_arc(t, r, a->get_info());
2277 MArc * ma = arcs.select(i);
2280 MNode * x = ma->get_src_node();
2281 MNode * y = ma->get_tgt_node();
2285 z->get_info().concat(y->get_info());
2287 contract_arc(mg, x, y, z, arcs);
2288 contract_arc(mg, y, x, z, arcs);
2299 nat_t min_cut = std::numeric_limits<nat_t>::max();
2301 SLList<Node<GT> *> ss;
2302 SLList<Node<GT> *> ts;
2305 for (
int i = 0; i < num_it; ++i)
2308 ArcSet arcs = build_arcs(mg);
2310 contract(mg, arcs, 2);
2316 if (cut_size >= min_cut)
2322 tmp_cut.
append(it.get_current()->get_info());
2329 ss.
swap(src->get_info());
2331 MNode * tgt = first_arc->get_tgt_node();
2332 ts.
swap(tgt->get_info());
2335 return std::make_tuple(std::move(ss), std::move(ts), std::move(cut));
2339 std::tuple<SLList<Node<GT> *>, SLList<Node<GT> *>,
SLList<Arc<GT> *>>
2345 return compute_min_cut(mg);
2350 ArcSet arcs1 = build_arcs(h1);
2351 contract(h1, arcs1, t);
2352 auto r1 = compute_min_cut_fast_rec(h1);
2355 ArcSet arcs2 = build_arcs(h2);
2356 contract(h2, arcs2, t);
2357 auto r2 = compute_min_cut_fast_rec(h2);
2359 if (std::get<2>(r1).size() < std::get<2>(r2).size())
2371 NodeOutput & node_out;
2372 ArcOutput & arc_out;
2373 GraphOutput & graph_out;
2375 using Sz =
typename GT::SetSizeType;
2379 GraphOutput & _graph_out)
2380 : node_out(_node_out), arc_out(_arc_out), graph_out(_graph_out)
2386 ArcOutput && _arc_out = ArcOutput(),
2387 GraphOutput && _graph_out = GraphOutput())
2388 : node_out(_node_out), arc_out(_arc_out), graph_out(_graph_out)
2393 void write_in_text_mode(
const GT &, std::ostream &);
2395 void write_in_bin_mode(
const GT &, std::ofstream &);
2399 write_in_text_mode(g, out);
2404 write_in_bin_mode(g, out);
2408 template <
class GT,
class NodeOutput,
class ArcOutput,
class GraphOutput>
2416 out << g.get_num_nodes() <<
' ' << g.get_num_arcs() <<
'\n';
2428 map_nodes_pos[p] = i++;
2431 g.for_each_arc([&] (
const Arc<GT> * a)
2433 Sz s = map_nodes_pos[a->get_src_node()];
2434 Sz t = map_nodes_pos[a->get_tgt_node()];
2435 out << s <<
' ' << t <<
' ';
2441 template <
class GT,
class NodeOutput,
class ArcOutput,
class GraphOutput>
2445 bool is_d = g.is_digraph();
2446 out.write(reinterpret_cast<char *>(&is_d),
sizeof(
bool));
2448 Sz num_nodes = g.get_num_nodes();
2449 Sz num_arcs = g.get_num_arcs();
2451 out.write(reinterpret_cast<char *>(&num_nodes),
sizeof(Sz));
2452 out.write(reinterpret_cast<char *>(&num_arcs),
sizeof(Sz));
2463 map_nodes_pos[
const_cast<Node<GT> *
>(p)] = i++;
2466 g.for_each_arc([&] (
Arc<GT> * a)
2468 Sz * s = &map_nodes_pos[a->get_src_node()];
2469 Sz * t = &map_nodes_pos[a->get_tgt_node()];
2470 out.write(reinterpret_cast<char *>(s),
sizeof(Sz));
2471 out.write(reinterpret_cast<char *>(t),
sizeof(Sz));
2482 NodeInput & node_in;
2484 GraphInput & graph_in;
2486 using Sz =
typename GT::SetSizeType;
2489 InputGraph(NodeInput & _node_in, ArcInput & _arc_in, GraphInput & _graph_in)
2490 : node_in(_node_in), arc_in(_arc_in), graph_in(_graph_in)
2496 ArcInput && _arc_in = ArcInput(),
2497 GraphInput && _graph_in = GraphInput())
2498 : node_in(_node_in), arc_in(_arc_in), graph_in(_graph_in)
2503 GT read_in_text_mode(std::istream &);
2505 GT read_in_bin_mode(std::ifstream &);
2509 return read_in_text_mode(in);
2514 return read_in_bin_mode(in);
2518 template <
class GT,
class NodeInput,
class ArcInput,
class GraphInput>
2527 if (g.is_digraph() xor (type ==
"digraph"))
2528 throw std::logic_error(
"Conflict between directed and undirected graph");
2533 in >> num_nodes >> num_arcs;
2538 for (Sz i = 0; i < num_nodes; ++i)
2545 for (Sz i = 0; i < num_arcs; ++i)
2553 Arc<GT> * a = g.insert_arc(src, tgt);
2560 template <
class GT,
class NodeInput,
class ArcInput,
class GraphInput>
2567 in.read(reinterpret_cast<char *>(&is_d),
sizeof(
bool));
2569 if (g.is_digraph() xor is_d)
2570 throw std::logic_error(
"Conflict between directed and undirected graph");
2575 in.read(reinterpret_cast<char *>(&num_nodes),
sizeof(Sz));
2576 in.read(reinterpret_cast<char *>(&num_arcs),
sizeof(Sz));
2582 for (Sz i = 0; i < num_nodes; ++i)
2589 for (Sz i = 0; i < num_arcs; ++i)
2592 in.read(reinterpret_cast<char *>(&s),
sizeof(Sz));
2594 in.read(reinterpret_cast<char *>(&t),
sizeof(Sz));
2597 Arc<GT> * a = g.insert_arc(src, tgt);
2610 NodeAttr & node_attr;
2612 GraphAttr & graph_attr;
2614 using Sz =
typename GT::SetSizeType;
2618 GraphAttr & _graph_attr)
2619 : node_attr(_node_attr), arc_attr(_arc_attr), graph_attr(_graph_attr)
2625 ArcAttr && _arc_attr = ArcAttr(),
2626 GraphAttr && _graph_attr = GraphAttr())
2627 : node_attr(_node_attr), arc_attr(_arc_attr), graph_attr(_graph_attr)
2632 void write_graph(
const GT &, std::ofstream &,
2633 const std::string & rankdir =
"LR");
2637 std::ofstream file(file_name.c_str());
2638 write_graph(g, file);
2643 template <
class GT,
class NodeAttr,
class ArcAttr,
class GraphAttr>
2645 write_graph(
const GT & g, std::ofstream & output,
const std::string & rankdir)
2648 <<
"File generated automatically by write_graph in DotGraph" 2657 output <<
" rankdir = " << rankdir <<
";\n\n";
2659 output << graph_attr(g) <<
"\n\n";
2661 output <<
" // Nodes \n\n";
2665 const std::string arc_connector = g.is_digraph() ?
"->" :
"--";
2669 g.for_each_node([&](
Node<GT> * node)
2671 output <<
" " << i <<
"[" << node_attr(node) <<
"];\n";
2676 output <<
"\n // Arcs \n\n";
2678 g.for_each_arc([&](
Arc<GT> * arc)
2680 Node<GT> * src_node = arc->get_src_node();
2681 Node<GT> * tgt_node = arc->get_tgt_node();
2682 Sz src_index = map[src_node];
2683 Sz tgt_index = map[tgt_node];
2686 << src_index << arc_connector << tgt_index
2697 # endif // DSGGRAPHALGORITHMS_H
Arc< GT > ArcType
Definition: graphalgorithms.H:1696
Definition: graphutilities.H:619
void paint_cut_nodes_connected_components_rec(const GT &, Node< GT > *, lint_t)
Definition: graphalgorithms.H:617
DotGraph(NodeAttr &&_node_attr=NodeAttr(), ArcAttr &&_arc_attr=ArcAttr(), GraphAttr &&_graph_attr=GraphAttr())
Definition: graphalgorithms.H:2624
bool remove(const Key &k)
Definition: map.H:372
Arc< GT > ArcType
Definition: graphalgorithms.H:1113
void build_subgraph_rec(const GT &, Node< GT > *, const GT &)
bool depth_first_search_path_rec(const GT &, Node< GT > *, Node< GT > *, Path< GT > &)
Definition: graphalgorithms.H:231
NodeInfo & get_info()
Definition: nodesdef.H:1032
void init(NodeType *start)
Definition: graphutilities.H:191
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut(const GT &g, nat_t num_it)
Definition: graphalgorithms.H:2223
SLList< GT > Kosaraju_compute_strong_connected_components(const GT &)
Definition: graphalgorithms.H:825
void write_graph(const GT &, std::ofstream &, const std::string &rankdir="LR")
Definition: graphalgorithms.H:2645
void depth_first_traverse_prefix(const GT &, Op &op)
Definition: graphalgorithms.H:329
void clear()
Definition: heap.H:988
void paint_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1141
Kruskal(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1125
T & append(const T &item)
Definition: list.H:265
Definition: graphalgorithms.H:1238
SLList< Node< GT > * > df_topological_sort(const GT &)
Definition: graphalgorithms.H:861
T get()
Definition: queue.H:519
typename GT::ArcIterator ArcIt
Definition: graphutilities.H:81
T random_uniform(rng_t &, T)
Definition: random.H:54
void remove_node(GNode *)
Definition: graph.H:1515
lint_t & df(Node< GT > *p)
Definition: graphutilities.H:458
void insert(ArcType *arc)
Definition: graphutilities.H:213
DistanceCmp(Distance &&d=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1094
Astar(Distance &&_distance=Distance(), Heuristic &&_heuristic=Heuristic(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1721
double real_t
Definition: types.H:51
void remove_last_node()
Definition: graphutilities.H:285
Arc< GT > * get_min_arc()
Definition: graphalgorithms.H:1268
void for_each_arc(Op &op) const
Definition: graph.H:321
GT build_min_path_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:1597
KargerMinCut()
Definition: graphalgorithms.H:2216
void breadth_first_traverse(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:877
void paint_from_cut_node(const GT &, Node< GT > *, lint_t &)
Definition: graphalgorithms.H:644
std::tuple< bool, GT > build_min_path_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:2083
Definition: graphalgorithms.H:2608
bool has_cycle(const GT &, Node< GT > *)
Definition: graphalgorithms.H:290
void for_each(Op &op) const
Definition: containeralgorithms.H:62
ArcHeapCmp(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1223
Definition: graphutilities.H:685
static constexpr Type MAX
Definition: graphalgorithms.H:1068
static constexpr Type ZERO
Definition: graphalgorithms.H:1067
Path< GT > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1730
bool is_graph_acyclique(const GT &, Node< GT > *)
std::mt19937_64 rng_t
Definition: types.H:52
GT build_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1318
void depth_first_traverse(const GT &g, Op &op)
Definition: graphalgorithms.H:62
Path< GT > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1468
SLList< GT > compute_connected_components(const GT &)
Definition: graphalgorithms.H:448
Dijkstra(Distance &_distance, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1432
void append(ArcType *arc)
Definition: graphutilities.H:247
SLList< SLList< Node< GT > * > > topological_ranks(const GT &)
Definition: graphalgorithms.H:1012
void write_in_text_mode(const GT &, std::ostream &)
Definition: graphalgorithms.H:2410
void depth_first_traverse_sufix_rec(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:206
nat_t get_num_arcs() const
Definition: graph.H:1096
bool paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:2021
BellmanFord(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1952
Path< GT > breadth_first_search_path(const GT &g, Node< GT > *, Node< GT > *)
Definition: graphalgorithms.H:912
Arc * get_first_arc()
Definition: graph.H:1075
typename GT::AdjacentArcIterator AdArcIt
Definition: graphutilities.H:82
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut_fast(const GT &g)
Definition: graphalgorithms.H:2239
Arc< GT > ArcType
Definition: graphalgorithms.H:1416
void for_each(Op &op) const
Definition: graphutilities.H:380
void Kosaraju_build_subgraph_rec(const GT &, Node< GT > *, const GT &, nat_t)
void build_cut_nodes_subgraph_rec(const GT &, Node< GT > *, const GT &, lint_t)
bool is_empty() const
Definition: queue.H:462
rng_t::result_type rng_seed_t
Definition: types.H:53
rng_seed_t get_random_seed()
Path< GT > depth_first_search_path(const GT &, Node< GT > *, Node< GT > *)
Definition: graphalgorithms.H:361
Astar(Distance &_distance, Heuristic &_heuristic, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1713
typename GT::Node Node
Definition: graphutilities.H:78
Definition: graphalgorithms.H:1082
Definition: graphalgorithms.H:1863
SLList< GT > build_cut_nodes_subgraphs(const GT &)
Definition: graphalgorithms.H:719
T & insert(const T &item)
Definition: list.H:249
void add_nodes_to_component_rec(const GT &, Node< GT > *, SLList< Node< GT > * > &)
Definition: graphalgorithms.H:473
void swap(SLList &l)
Definition: list.H:325
Definition: graphutilities.H:669
long long lint_t
Definition: types.H:49
SLList< SLList< Node< GT > * > > connected_components_node_list(const GT &)
Definition: graphalgorithms.H:499
SLList< Node< GT > * > bf_topological_sort(const GT &)
Definition: graphalgorithms.H:971
std::tuple< GT, SLList< Arc< GT > * > > build_cut_graph(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:743
OutputGraph(NodeOutput &&_node_out=NodeOutput(), ArcOutput &&_arc_out=ArcOutput(), GraphOutput &&_graph_out=GraphOutput())
Definition: graphalgorithms.H:2385
Definition: graphalgorithms.H:1109
Definition: graphalgorithms.H:1062
void paint_min_spanning_tree(const GT &g)
Definition: graphalgorithms.H:1344
Definition: italgorithms.H:33
DotGraph(NodeAttr &_node_attr, ArcAttr &_arc_attr, GraphAttr &_graph_attr)
Definition: graphalgorithms.H:2617
Node< GT > NodeType
Definition: graphalgorithms.H:1415
GraphNode * get_src_node()
Definition: nodesdef.H:1081
Definition: graphutilities.H:777
std::tuple< SLList< Node< GT > * >, SLList< Node< GT > * >, SLList< Arc< GT > * > > compute_min_cut(const GT &g)
Definition: graphalgorithms.H:2233
void insert_arc(Arc< GT > *a, Node< GT > *t)
Definition: graphalgorithms.H:1249
Prim(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1304
KargerMinCut(rng_seed_t seed)
Definition: graphalgorithms.H:2210
ArcHeapCmp(Distance &_distance, Cmp &_cmp)
Definition: graphalgorithms.H:1218
void paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1495
DistanceCmp(Distance &d, Cmp &_cmp)
Definition: graphalgorithms.H:1088
Arc * insert_arc(Node *s, Node *t)
Definition: graph.H:1119
std::tuple< SLList< GT >, GT, SLList< Arc< GT > * > > compute_cut_nodes_connected_components(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:778
Node * insert_node()
Definition: graph.H:1101
Node< GT > NodeType
Definition: graphalgorithms.H:1292
Node< GT > NodeType
Definition: graphalgorithms.H:1112
void reset_nodes() const
Definition: graph.H:816
Definition: graphutilities.H:765
GT build_min_spanning_tree(const GT &)
Definition: graphalgorithms.H:1162
Definition: graphutilities.H:789
void paint_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1757
Definition: graphutilities.H:123
void destroy_node_info(const GT &g)
Definition: graphutilities.H:561
Definition: graphalgorithms.H:1289
Dijkstra(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp(), Plus &&_plus=Plus())
Definition: graphalgorithms.H:1438
Definition: graphalgorithms.H:1692
Prim(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1310
void depth_first_traverse_prefix_rec(const GT &, Node< GT > *, Op &)
Definition: graphalgorithms.H:182
Arc< GT > ArcType
Definition: graphalgorithms.H:1293
void write_graph(const GT &g, const std::string &file_name)
Definition: graphalgorithms.H:2635
bool is_empty() const
Definition: heap.H:905
unsigned long int nat_t
Definition: types.H:50
Definition: graphalgorithms.H:2369
typename GT::NodeIterator NodeIt
Definition: graphutilities.H:80
bool test_cycle_rec(const GT &, Node< GT > *, bool)
Definition: graphalgorithms.H:264
void write_in_bin_mode(const GT &, std::ofstream &)
Definition: graphalgorithms.H:2443
Node< GT > NodeType
Definition: graphalgorithms.H:1695
Definition: relation.H:54
typename GT::ArcInfoType Type
Definition: graphalgorithms.H:1065
Value * search(const Key &k)
Definition: map.H:254
Definition: graphalgorithms.H:1212
void join(const T &tp, const T &tq)
Definition: relation.H:103
Distance::Type & ACC(Node< GT > *p)
Definition: graphutilities.H:513
Definition: graphalgorithms.H:2138
Definition: graphalgorithms.H:1678
GraphTag
Definition: graphutilities.H:37
void for_each_node(Op &op) const
Definition: graph.H:112
void compute_cut_nodes_rec(const GT &, Node< GT > *, Arc< GT > &, SLList< Node< GT > * > &, lint_t &)
void paint_min_spanning_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1323
void paint_min_path_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1447
typename GT::Arc Arc
Definition: graphutilities.H:79
Definition: graphutilities.H:701
nat_t get_num_nodes() const
Definition: graph.H:1091
SLList< Node< GT > * > compute_cut_nodes(const GT &)
Definition: graphalgorithms.H:570
std::tuple< bool, Path< GT > > search_min_path(const GT &g, Node< GT > *start, Node< GT > *end)
Definition: graphalgorithms.H:1988
bool paint_min_path_tree(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:1961
BellmanFord(Distance &_distance, Cmp &_cmp, Plus &_plus)
Definition: graphalgorithms.H:1946
OutputGraph(NodeOutput &_node_out, ArcOutput &_arc_out, GraphOutput &_graph_out)
Definition: graphalgorithms.H:2378
void depth_first_traverse_sufix(const GT &, Op &op)
Definition: graphalgorithms.H:345
GT build_min_spanning_tree(const GT &, Node< GT > *)
Definition: graphalgorithms.H:1351
T & put(const T &item)
Definition: queue.H:509
lint_t paint_cut_nodes_subgraphs(const GT &, const SLList< Node< GT > * > &)
Definition: graphalgorithms.H:670
Definition: graphalgorithms.H:1412
Kruskal(Distance &&_distance=Distance(), Cmp &&_cmp=Cmp())
Definition: graphalgorithms.H:1131
GT invert_digraph(const GT &, bool)
Type & operator()(Arc< GT > &a)
Definition: graphalgorithms.H:1070
bool is_acyclique(const GT &g, Node< GT > *start)
Definition: graphalgorithms.H:310