1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_PREFLOW_H
20 #define LEMON_PREFLOW_H
22 #include <lemon/tolerance.h>
23 #include <lemon/elevator.h>
27 /// \brief Implementation of the preflow algorithm.
31 /// \brief Default traits class of Preflow class.
33 /// Default traits class of Preflow class.
34 /// \tparam _Digraph Digraph type.
35 /// \tparam _CapacityMap Capacity map type.
36 template <typename _Digraph, typename _CapacityMap>
37 struct PreflowDefaultTraits {
39 /// \brief The type of the digraph the algorithm runs on.
40 typedef _Digraph Digraph;
42 /// \brief The type of the map that stores the arc capacities.
44 /// The type of the map that stores the arc capacities.
45 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46 typedef _CapacityMap CapacityMap;
48 /// \brief The type of the flow values.
49 typedef typename CapacityMap::Value Value;
51 /// \brief The type of the map that stores the flow values.
53 /// The type of the map that stores the flow values.
54 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55 typedef typename Digraph::template ArcMap<Value> FlowMap;
57 /// \brief Instantiates a FlowMap.
59 /// This function instantiates a \ref FlowMap.
60 /// \param digraph The digraph, to which we would like to define
62 static FlowMap* createFlowMap(const Digraph& digraph) {
63 return new FlowMap(digraph);
66 /// \brief The elevator type used by Preflow algorithm.
68 /// The elevator type used by Preflow algorithm.
71 /// \sa LinkedElevator
72 typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
74 /// \brief Instantiates an Elevator.
76 /// This function instantiates an \ref Elevator.
77 /// \param digraph The digraph, to which we would like to define
79 /// \param max_level The maximum level of the elevator.
80 static Elevator* createElevator(const Digraph& digraph, int max_level) {
81 return new Elevator(digraph, max_level);
84 /// \brief The tolerance used by the algorithm
86 /// The tolerance used by the algorithm to handle inexact computation.
87 typedef lemon::Tolerance<Value> Tolerance;
94 /// \brief %Preflow algorithm class.
96 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
97 /// \e push-relabel algorithm producing a flow of maximum value in a
98 /// digraph. The preflow algorithms are the fastest known maximum
99 /// flow algorithms. The current implementation use a mixture of the
100 /// \e "highest label" and the \e "bound decrease" heuristics.
101 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
103 /// The algorithm consists of two phases. After the first phase
104 /// the maximum flow value and the minimum cut is obtained. The
105 /// second phase constructs a feasible maximum flow on each arc.
107 /// \tparam _Digraph The type of the digraph the algorithm runs on.
108 /// \tparam _CapacityMap The type of the capacity map. The default map
109 /// type is \ref concepts::Digraph::ArcMap "_Digraph::ArcMap<int>".
111 template <typename _Digraph, typename _CapacityMap, typename _Traits>
113 template <typename _Digraph,
114 typename _CapacityMap = typename _Digraph::template ArcMap<int>,
115 typename _Traits = PreflowDefaultTraits<_Digraph, _CapacityMap> >
120 ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
121 typedef _Traits Traits;
122 ///The type of the digraph the algorithm runs on.
123 typedef typename Traits::Digraph Digraph;
124 ///The type of the capacity map.
125 typedef typename Traits::CapacityMap CapacityMap;
126 ///The type of the flow values.
127 typedef typename Traits::Value Value;
129 ///The type of the flow map.
130 typedef typename Traits::FlowMap FlowMap;
131 ///The type of the elevator.
132 typedef typename Traits::Elevator Elevator;
133 ///The type of the tolerance.
134 typedef typename Traits::Tolerance Tolerance;
138 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
140 const Digraph& _graph;
141 const CapacityMap* _capacity;
145 Node _source, _target;
153 typedef typename Digraph::template NodeMap<Value> ExcessMap;
156 Tolerance _tolerance;
161 void createStructures() {
162 _node_num = countNodes(_graph);
165 _flow = Traits::createFlowMap(_graph);
169 _level = Traits::createElevator(_graph, _node_num);
173 _excess = new ExcessMap(_graph);
177 void destroyStructures() {
191 typedef Preflow Create;
193 ///\name Named Template Parameters
197 template <typename _FlowMap>
198 struct SetFlowMapTraits : public Traits {
199 typedef _FlowMap FlowMap;
200 static FlowMap *createFlowMap(const Digraph&) {
201 LEMON_ASSERT(false, "FlowMap is not initialized");
202 return 0; // ignore warnings
206 /// \brief \ref named-templ-param "Named parameter" for setting
209 /// \ref named-templ-param "Named parameter" for setting FlowMap
211 template <typename _FlowMap>
213 : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<_FlowMap> > {
214 typedef Preflow<Digraph, CapacityMap,
215 SetFlowMapTraits<_FlowMap> > Create;
218 template <typename _Elevator>
219 struct SetElevatorTraits : public Traits {
220 typedef _Elevator Elevator;
221 static Elevator *createElevator(const Digraph&, int) {
222 LEMON_ASSERT(false, "Elevator is not initialized");
223 return 0; // ignore warnings
227 /// \brief \ref named-templ-param "Named parameter" for setting
230 /// \ref named-templ-param "Named parameter" for setting Elevator
231 /// type. If this named parameter is used, then an external
232 /// elevator object must be passed to the algorithm using the
233 /// \ref elevator(Elevator&) "elevator()" function before calling
234 /// \ref run() or \ref init().
235 /// \sa SetStandardElevator
236 template <typename _Elevator>
238 : public Preflow<Digraph, CapacityMap, SetElevatorTraits<_Elevator> > {
239 typedef Preflow<Digraph, CapacityMap,
240 SetElevatorTraits<_Elevator> > Create;
243 template <typename _Elevator>
244 struct SetStandardElevatorTraits : public Traits {
245 typedef _Elevator Elevator;
246 static Elevator *createElevator(const Digraph& digraph, int max_level) {
247 return new Elevator(digraph, max_level);
251 /// \brief \ref named-templ-param "Named parameter" for setting
252 /// Elevator type with automatic allocation
254 /// \ref named-templ-param "Named parameter" for setting Elevator
255 /// type with automatic allocation.
256 /// The Elevator should have standard constructor interface to be
257 /// able to automatically created by the algorithm (i.e. the
258 /// digraph and the maximum level should be passed to it).
259 /// However an external elevator object could also be passed to the
260 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
261 /// before calling \ref run() or \ref init().
263 template <typename _Elevator>
264 struct SetStandardElevator
265 : public Preflow<Digraph, CapacityMap,
266 SetStandardElevatorTraits<_Elevator> > {
267 typedef Preflow<Digraph, CapacityMap,
268 SetStandardElevatorTraits<_Elevator> > Create;
280 /// \brief The constructor of the class.
282 /// The constructor of the class.
283 /// \param digraph The digraph the algorithm runs on.
284 /// \param capacity The capacity of the arcs.
285 /// \param source The source node.
286 /// \param target The target node.
287 Preflow(const Digraph& digraph, const CapacityMap& capacity,
288 Node source, Node target)
289 : _graph(digraph), _capacity(&capacity),
290 _node_num(0), _source(source), _target(target),
291 _flow(0), _local_flow(false),
292 _level(0), _local_level(false),
293 _excess(0), _tolerance(), _phase() {}
295 /// \brief Destructor.
302 /// \brief Sets the capacity map.
304 /// Sets the capacity map.
305 /// \return <tt>(*this)</tt>
306 Preflow& capacityMap(const CapacityMap& map) {
311 /// \brief Sets the flow map.
313 /// Sets the flow map.
314 /// If you don't use this function before calling \ref run() or
315 /// \ref init(), an instance will be allocated automatically.
316 /// The destructor deallocates this automatically allocated map,
318 /// \return <tt>(*this)</tt>
319 Preflow& flowMap(FlowMap& map) {
328 /// \brief Sets the source node.
330 /// Sets the source node.
331 /// \return <tt>(*this)</tt>
332 Preflow& source(const Node& node) {
337 /// \brief Sets the target node.
339 /// Sets the target node.
340 /// \return <tt>(*this)</tt>
341 Preflow& target(const Node& node) {
346 /// \brief Sets the elevator used by algorithm.
348 /// Sets the elevator used by algorithm.
349 /// If you don't use this function before calling \ref run() or
350 /// \ref init(), an instance will be allocated automatically.
351 /// The destructor deallocates this automatically allocated elevator,
353 /// \return <tt>(*this)</tt>
354 Preflow& elevator(Elevator& elevator) {
357 _local_level = false;
363 /// \brief Returns a const reference to the elevator.
365 /// Returns a const reference to the elevator.
367 /// \pre Either \ref run() or \ref init() must be called before
368 /// using this function.
369 const Elevator& elevator() const {
373 /// \brief Sets the tolerance used by algorithm.
375 /// Sets the tolerance used by algorithm.
376 Preflow& tolerance(const Tolerance& tolerance) const {
377 _tolerance = tolerance;
381 /// \brief Returns a const reference to the tolerance.
383 /// Returns a const reference to the tolerance.
384 const Tolerance& tolerance() const {
388 /// \name Execution Control
389 /// The simplest way to execute the preflow algorithm is to use
390 /// \ref run() or \ref runMinCut().\n
391 /// If you need more control on the initial solution or the execution,
392 /// first you have to call one of the \ref init() functions, then
393 /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
397 /// \brief Initializes the internal data structures.
399 /// Initializes the internal data structures and sets the initial
400 /// flow to zero on each arc.
405 for (NodeIt n(_graph); n != INVALID; ++n) {
409 for (ArcIt e(_graph); e != INVALID; ++e) {
413 typename Digraph::template NodeMap<bool> reached(_graph, false);
416 _level->initAddItem(_target);
418 std::vector<Node> queue;
419 reached.set(_source, true);
421 queue.push_back(_target);
422 reached.set(_target, true);
423 while (!queue.empty()) {
424 _level->initNewLevel();
425 std::vector<Node> nqueue;
426 for (int i = 0; i < int(queue.size()); ++i) {
428 for (InArcIt e(_graph, n); e != INVALID; ++e) {
429 Node u = _graph.source(e);
430 if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
431 reached.set(u, true);
432 _level->initAddItem(u);
439 _level->initFinish();
441 for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
442 if (_tolerance.positive((*_capacity)[e])) {
443 Node u = _graph.target(e);
444 if ((*_level)[u] == _level->maxLevel()) continue;
445 _flow->set(e, (*_capacity)[e]);
446 _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
447 if (u != _target && !_level->active(u)) {
454 /// \brief Initializes the internal data structures using the
457 /// Initializes the internal data structures and sets the initial
458 /// flow to the given \c flowMap. The \c flowMap should contain a
459 /// flow or at least a preflow, i.e. at each node excluding the
460 /// source node the incoming flow should greater or equal to the
462 /// \return \c false if the given \c flowMap is not a preflow.
463 template <typename FlowMap>
464 bool init(const FlowMap& flowMap) {
467 for (ArcIt e(_graph); e != INVALID; ++e) {
468 _flow->set(e, flowMap[e]);
471 for (NodeIt n(_graph); n != INVALID; ++n) {
473 for (InArcIt e(_graph, n); e != INVALID; ++e) {
474 excess += (*_flow)[e];
476 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
477 excess -= (*_flow)[e];
479 if (excess < 0 && n != _source) return false;
480 _excess->set(n, excess);
483 typename Digraph::template NodeMap<bool> reached(_graph, false);
486 _level->initAddItem(_target);
488 std::vector<Node> queue;
489 reached.set(_source, true);
491 queue.push_back(_target);
492 reached.set(_target, true);
493 while (!queue.empty()) {
494 _level->initNewLevel();
495 std::vector<Node> nqueue;
496 for (int i = 0; i < int(queue.size()); ++i) {
498 for (InArcIt e(_graph, n); e != INVALID; ++e) {
499 Node u = _graph.source(e);
501 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
502 reached.set(u, true);
503 _level->initAddItem(u);
507 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
508 Node v = _graph.target(e);
509 if (!reached[v] && _tolerance.positive((*_flow)[e])) {
510 reached.set(v, true);
511 _level->initAddItem(v);
518 _level->initFinish();
520 for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
521 Value rem = (*_capacity)[e] - (*_flow)[e];
522 if (_tolerance.positive(rem)) {
523 Node u = _graph.target(e);
524 if ((*_level)[u] == _level->maxLevel()) continue;
525 _flow->set(e, (*_capacity)[e]);
526 _excess->set(u, (*_excess)[u] + rem);
527 if (u != _target && !_level->active(u)) {
532 for (InArcIt e(_graph, _source); e != INVALID; ++e) {
533 Value rem = (*_flow)[e];
534 if (_tolerance.positive(rem)) {
535 Node v = _graph.source(e);
536 if ((*_level)[v] == _level->maxLevel()) continue;
538 _excess->set(v, (*_excess)[v] + rem);
539 if (v != _target && !_level->active(v)) {
547 /// \brief Starts the first phase of the preflow algorithm.
549 /// The preflow algorithm consists of two phases, this method runs
550 /// the first phase. After the first phase the maximum flow value
551 /// and a minimum value cut can already be computed, although a
552 /// maximum flow is not yet obtained. So after calling this method
553 /// \ref flowValue() returns the value of a maximum flow and \ref
554 /// minCut() returns a minimum cut.
555 /// \pre One of the \ref init() functions must be called before
556 /// using this function.
557 void startFirstPhase() {
560 Node n = _level->highestActive();
561 int level = _level->highestActiveLevel();
562 while (n != INVALID) {
565 while (num > 0 && n != INVALID) {
566 Value excess = (*_excess)[n];
567 int new_level = _level->maxLevel();
569 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
570 Value rem = (*_capacity)[e] - (*_flow)[e];
571 if (!_tolerance.positive(rem)) continue;
572 Node v = _graph.target(e);
573 if ((*_level)[v] < level) {
574 if (!_level->active(v) && v != _target) {
577 if (!_tolerance.less(rem, excess)) {
578 _flow->set(e, (*_flow)[e] + excess);
579 _excess->set(v, (*_excess)[v] + excess);
584 _excess->set(v, (*_excess)[v] + rem);
585 _flow->set(e, (*_capacity)[e]);
587 } else if (new_level > (*_level)[v]) {
588 new_level = (*_level)[v];
592 for (InArcIt e(_graph, n); e != INVALID; ++e) {
593 Value rem = (*_flow)[e];
594 if (!_tolerance.positive(rem)) continue;
595 Node v = _graph.source(e);
596 if ((*_level)[v] < level) {
597 if (!_level->active(v) && v != _target) {
600 if (!_tolerance.less(rem, excess)) {
601 _flow->set(e, (*_flow)[e] - excess);
602 _excess->set(v, (*_excess)[v] + excess);
607 _excess->set(v, (*_excess)[v] + rem);
610 } else if (new_level > (*_level)[v]) {
611 new_level = (*_level)[v];
617 _excess->set(n, excess);
620 if (new_level + 1 < _level->maxLevel()) {
621 _level->liftHighestActive(new_level + 1);
623 _level->liftHighestActiveToTop();
625 if (_level->emptyLevel(level)) {
626 _level->liftToTop(level);
629 _level->deactivate(n);
632 n = _level->highestActive();
633 level = _level->highestActiveLevel();
637 num = _node_num * 20;
638 while (num > 0 && n != INVALID) {
639 Value excess = (*_excess)[n];
640 int new_level = _level->maxLevel();
642 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
643 Value rem = (*_capacity)[e] - (*_flow)[e];
644 if (!_tolerance.positive(rem)) continue;
645 Node v = _graph.target(e);
646 if ((*_level)[v] < level) {
647 if (!_level->active(v) && v != _target) {
650 if (!_tolerance.less(rem, excess)) {
651 _flow->set(e, (*_flow)[e] + excess);
652 _excess->set(v, (*_excess)[v] + excess);
657 _excess->set(v, (*_excess)[v] + rem);
658 _flow->set(e, (*_capacity)[e]);
660 } else if (new_level > (*_level)[v]) {
661 new_level = (*_level)[v];
665 for (InArcIt e(_graph, n); e != INVALID; ++e) {
666 Value rem = (*_flow)[e];
667 if (!_tolerance.positive(rem)) continue;
668 Node v = _graph.source(e);
669 if ((*_level)[v] < level) {
670 if (!_level->active(v) && v != _target) {
673 if (!_tolerance.less(rem, excess)) {
674 _flow->set(e, (*_flow)[e] - excess);
675 _excess->set(v, (*_excess)[v] + excess);
680 _excess->set(v, (*_excess)[v] + rem);
683 } else if (new_level > (*_level)[v]) {
684 new_level = (*_level)[v];
690 _excess->set(n, excess);
693 if (new_level + 1 < _level->maxLevel()) {
694 _level->liftActiveOn(level, new_level + 1);
696 _level->liftActiveToTop(level);
698 if (_level->emptyLevel(level)) {
699 _level->liftToTop(level);
702 _level->deactivate(n);
705 while (level >= 0 && _level->activeFree(level)) {
709 n = _level->highestActive();
710 level = _level->highestActiveLevel();
712 n = _level->activeOn(level);
719 /// \brief Starts the second phase of the preflow algorithm.
721 /// The preflow algorithm consists of two phases, this method runs
722 /// the second phase. After calling one of the \ref init() functions
723 /// and \ref startFirstPhase() and then \ref startSecondPhase(),
724 /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
725 /// value of a maximum flow, \ref minCut() returns a minimum cut
726 /// \pre One of the \ref init() functions and \ref startFirstPhase()
727 /// must be called before using this function.
728 void startSecondPhase() {
731 typename Digraph::template NodeMap<bool> reached(_graph);
732 for (NodeIt n(_graph); n != INVALID; ++n) {
733 reached.set(n, (*_level)[n] < _level->maxLevel());
737 _level->initAddItem(_source);
739 std::vector<Node> queue;
740 queue.push_back(_source);
741 reached.set(_source, true);
743 while (!queue.empty()) {
744 _level->initNewLevel();
745 std::vector<Node> nqueue;
746 for (int i = 0; i < int(queue.size()); ++i) {
748 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
749 Node v = _graph.target(e);
750 if (!reached[v] && _tolerance.positive((*_flow)[e])) {
751 reached.set(v, true);
752 _level->initAddItem(v);
756 for (InArcIt e(_graph, n); e != INVALID; ++e) {
757 Node u = _graph.source(e);
759 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
760 reached.set(u, true);
761 _level->initAddItem(u);
768 _level->initFinish();
770 for (NodeIt n(_graph); n != INVALID; ++n) {
772 _level->dirtyTopButOne(n);
773 } else if ((*_excess)[n] > 0 && _target != n) {
779 while ((n = _level->highestActive()) != INVALID) {
780 Value excess = (*_excess)[n];
781 int level = _level->highestActiveLevel();
782 int new_level = _level->maxLevel();
784 for (OutArcIt e(_graph, n); e != INVALID; ++e) {
785 Value rem = (*_capacity)[e] - (*_flow)[e];
786 if (!_tolerance.positive(rem)) continue;
787 Node v = _graph.target(e);
788 if ((*_level)[v] < level) {
789 if (!_level->active(v) && v != _source) {
792 if (!_tolerance.less(rem, excess)) {
793 _flow->set(e, (*_flow)[e] + excess);
794 _excess->set(v, (*_excess)[v] + excess);
799 _excess->set(v, (*_excess)[v] + rem);
800 _flow->set(e, (*_capacity)[e]);
802 } else if (new_level > (*_level)[v]) {
803 new_level = (*_level)[v];
807 for (InArcIt e(_graph, n); e != INVALID; ++e) {
808 Value rem = (*_flow)[e];
809 if (!_tolerance.positive(rem)) continue;
810 Node v = _graph.source(e);
811 if ((*_level)[v] < level) {
812 if (!_level->active(v) && v != _source) {
815 if (!_tolerance.less(rem, excess)) {
816 _flow->set(e, (*_flow)[e] - excess);
817 _excess->set(v, (*_excess)[v] + excess);
822 _excess->set(v, (*_excess)[v] + rem);
825 } else if (new_level > (*_level)[v]) {
826 new_level = (*_level)[v];
832 _excess->set(n, excess);
835 if (new_level + 1 < _level->maxLevel()) {
836 _level->liftHighestActive(new_level + 1);
839 _level->liftHighestActiveToTop();
841 if (_level->emptyLevel(level)) {
843 _level->liftToTop(level);
846 _level->deactivate(n);
852 /// \brief Runs the preflow algorithm.
854 /// Runs the preflow algorithm.
855 /// \note pf.run() is just a shortcut of the following code.
858 /// pf.startFirstPhase();
859 /// pf.startSecondPhase();
867 /// \brief Runs the preflow algorithm to compute the minimum cut.
869 /// Runs the preflow algorithm to compute the minimum cut.
870 /// \note pf.runMinCut() is just a shortcut of the following code.
873 /// pf.startFirstPhase();
882 /// \name Query Functions
883 /// The results of the preflow algorithm can be obtained using these
885 /// Either one of the \ref run() "run*()" functions or one of the
886 /// \ref startFirstPhase() "start*()" functions should be called
887 /// before using them.
891 /// \brief Returns the value of the maximum flow.
893 /// Returns the value of the maximum flow by returning the excess
894 /// of the target node. This value equals to the value of
895 /// the maximum flow already after the first phase of the algorithm.
897 /// \pre Either \ref run() or \ref init() must be called before
898 /// using this function.
899 Value flowValue() const {
900 return (*_excess)[_target];
903 /// \brief Returns the flow on the given arc.
905 /// Returns the flow on the given arc. This method can
906 /// be called after the second phase of the algorithm.
908 /// \pre Either \ref run() or \ref init() must be called before
909 /// using this function.
910 Value flow(const Arc& arc) const {
911 return (*_flow)[arc];
914 /// \brief Returns a const reference to the flow map.
916 /// Returns a const reference to the arc map storing the found flow.
917 /// This method can be called after the second phase of the algorithm.
919 /// \pre Either \ref run() or \ref init() must be called before
920 /// using this function.
921 const FlowMap& flowMap() const {
925 /// \brief Returns \c true when the node is on the source side of the
928 /// Returns true when the node is on the source side of the found
929 /// minimum cut. This method can be called both after running \ref
930 /// startFirstPhase() and \ref startSecondPhase().
932 /// \pre Either \ref run() or \ref init() must be called before
933 /// using this function.
934 bool minCut(const Node& node) const {
935 return ((*_level)[node] == _level->maxLevel()) == _phase;
938 /// \brief Gives back a minimum value cut.
940 /// Sets \c cutMap to the characteristic vector of a minimum value
941 /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
942 /// node map with \c bool (or convertible) value type.
944 /// This method can be called both after running \ref startFirstPhase()
945 /// and \ref startSecondPhase(). The result after the second phase
946 /// could be slightly different if inexact computation is used.
948 /// \note This function calls \ref minCut() for each node, so it runs in
951 /// \pre Either \ref run() or \ref init() must be called before
952 /// using this function.
953 template <typename CutMap>
954 void minCutMap(CutMap& cutMap) const {
955 for (NodeIt n(_graph); n != INVALID; ++n) {
956 cutMap.set(n, minCut(n));