lemon/nagamochi_ibaraki.h
changeset 936 ddd3c0d3d9bf
child 978 eb252f805431
equal deleted inserted replaced
-1:000000000000 0:7f5b8c284ebe
       
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
       
     2  *
       
     3  * This file is a part of LEMON, a generic C++ optimization library.
       
     4  *
       
     5  * Copyright (C) 2003-2010
       
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     8  *
       
     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.
       
    12  *
       
    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
       
    15  * purpose.
       
    16  *
       
    17  */
       
    18 
       
    19 #ifndef LEMON_NAGAMOCHI_IBARAKI_H
       
    20 #define LEMON_NAGAMOCHI_IBARAKI_H
       
    21 
       
    22 
       
    23 /// \ingroup min_cut
       
    24 /// \file
       
    25 /// \brief Implementation of the Nagamochi-Ibaraki algorithm.
       
    26 
       
    27 #include <lemon/core.h>
       
    28 #include <lemon/bin_heap.h>
       
    29 #include <lemon/bucket_heap.h>
       
    30 #include <lemon/maps.h>
       
    31 #include <lemon/radix_sort.h>
       
    32 #include <lemon/unionfind.h>
       
    33 
       
    34 #include <cassert>
       
    35 
       
    36 namespace lemon {
       
    37 
       
    38   /// \brief Default traits class for NagamochiIbaraki class.
       
    39   ///
       
    40   /// Default traits class for NagamochiIbaraki class.
       
    41   /// \param GR The undirected graph type.
       
    42   /// \param CM Type of capacity map.
       
    43   template <typename GR, typename CM>
       
    44   struct NagamochiIbarakiDefaultTraits {
       
    45     /// The type of the capacity map.
       
    46     typedef typename CM::Value Value;
       
    47 
       
    48     /// The undirected graph type the algorithm runs on.
       
    49     typedef GR Graph;
       
    50 
       
    51     /// \brief The type of the map that stores the edge capacities.
       
    52     ///
       
    53     /// The type of the map that stores the edge capacities.
       
    54     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
       
    55     typedef CM CapacityMap;
       
    56 
       
    57     /// \brief Instantiates a CapacityMap.
       
    58     ///
       
    59     /// This function instantiates a \ref CapacityMap.
       
    60 #ifdef DOXYGEN
       
    61     static CapacityMap *createCapacityMap(const Graph& graph)
       
    62 #else
       
    63     static CapacityMap *createCapacityMap(const Graph&)
       
    64 #endif
       
    65     {
       
    66         LEMON_ASSERT(false, "CapacityMap is not initialized");
       
    67         return 0; // ignore warnings
       
    68     }
       
    69 
       
    70     /// \brief The cross reference type used by heap.
       
    71     ///
       
    72     /// The cross reference type used by heap.
       
    73     /// Usually \c Graph::NodeMap<int>.
       
    74     typedef typename Graph::template NodeMap<int> HeapCrossRef;
       
    75 
       
    76     /// \brief Instantiates a HeapCrossRef.
       
    77     ///
       
    78     /// This function instantiates a \ref HeapCrossRef.
       
    79     /// \param g is the graph, to which we would like to define the
       
    80     /// \ref HeapCrossRef.
       
    81     static HeapCrossRef *createHeapCrossRef(const Graph& g) {
       
    82       return new HeapCrossRef(g);
       
    83     }
       
    84 
       
    85     /// \brief The heap type used by NagamochiIbaraki algorithm.
       
    86     ///
       
    87     /// The heap type used by NagamochiIbaraki algorithm. It has to
       
    88     /// maximize the priorities.
       
    89     ///
       
    90     /// \sa BinHeap
       
    91     /// \sa NagamochiIbaraki
       
    92     typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
       
    93 
       
    94     /// \brief Instantiates a Heap.
       
    95     ///
       
    96     /// This function instantiates a \ref Heap.
       
    97     /// \param r is the cross reference of the heap.
       
    98     static Heap *createHeap(HeapCrossRef& r) {
       
    99       return new Heap(r);
       
   100     }
       
   101   };
       
   102 
       
   103   /// \ingroup min_cut
       
   104   ///
       
   105   /// \brief Calculates the minimum cut in an undirected graph.
       
   106   ///
       
   107   /// Calculates the minimum cut in an undirected graph with the
       
   108   /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
       
   109   /// nodes into two partitions with the minimum sum of edge capacities
       
   110   /// between the two partitions. The algorithm can be used to test
       
   111   /// the network reliability, especially to test how many links have
       
   112   /// to be destroyed in the network to split it to at least two
       
   113   /// distinict subnetworks.
       
   114   ///
       
   115   /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
       
   116   /// \ref FibHeap "Fibonacci heap" it can be decreased to
       
   117   /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
       
   118   /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
       
   119   /// complexity.
       
   120   ///
       
   121   /// \warning The value type of the capacity map should be able to
       
   122   /// hold any cut value of the graph, otherwise the result can
       
   123   /// overflow.
       
   124   /// \note This capacity is supposed to be integer type.
       
   125 #ifdef DOXYGEN
       
   126   template <typename GR, typename CM, typename TR>
       
   127 #else
       
   128   template <typename GR,
       
   129             typename CM = typename GR::template EdgeMap<int>,
       
   130             typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
       
   131 #endif
       
   132   class NagamochiIbaraki {
       
   133   public:
       
   134 
       
   135     typedef TR Traits;
       
   136     /// The type of the underlying graph.
       
   137     typedef typename Traits::Graph Graph;
       
   138 
       
   139     /// The type of the capacity map.
       
   140     typedef typename Traits::CapacityMap CapacityMap;
       
   141     /// The value type of the capacity map.
       
   142     typedef typename Traits::CapacityMap::Value Value;
       
   143 
       
   144     /// The heap type used by the algorithm.
       
   145     typedef typename Traits::Heap Heap;
       
   146     /// The cross reference type used for the heap.
       
   147     typedef typename Traits::HeapCrossRef HeapCrossRef;
       
   148 
       
   149     ///\name Named template parameters
       
   150 
       
   151     ///@{
       
   152 
       
   153     struct SetUnitCapacityTraits : public Traits {
       
   154       typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
       
   155       static CapacityMap *createCapacityMap(const Graph&) {
       
   156         return new CapacityMap();
       
   157       }
       
   158     };
       
   159 
       
   160     /// \brief \ref named-templ-param "Named parameter" for setting
       
   161     /// the capacity map to a constMap<Edge, int, 1>() instance
       
   162     ///
       
   163     /// \ref named-templ-param "Named parameter" for setting
       
   164     /// the capacity map to a constMap<Edge, int, 1>() instance
       
   165     struct SetUnitCapacity
       
   166       : public NagamochiIbaraki<Graph, CapacityMap,
       
   167                                 SetUnitCapacityTraits> {
       
   168       typedef NagamochiIbaraki<Graph, CapacityMap,
       
   169                                SetUnitCapacityTraits> Create;
       
   170     };
       
   171 
       
   172 
       
   173     template <class H, class CR>
       
   174     struct SetHeapTraits : public Traits {
       
   175       typedef CR HeapCrossRef;
       
   176       typedef H Heap;
       
   177       static HeapCrossRef *createHeapCrossRef(int num) {
       
   178         LEMON_ASSERT(false, "HeapCrossRef is not initialized");
       
   179         return 0; // ignore warnings
       
   180       }
       
   181       static Heap *createHeap(HeapCrossRef &) {
       
   182         LEMON_ASSERT(false, "Heap is not initialized");
       
   183         return 0; // ignore warnings
       
   184       }
       
   185     };
       
   186 
       
   187     /// \brief \ref named-templ-param "Named parameter" for setting
       
   188     /// heap and cross reference type
       
   189     ///
       
   190     /// \ref named-templ-param "Named parameter" for setting heap and
       
   191     /// cross reference type. The heap has to maximize the priorities.
       
   192     template <class H, class CR = RangeMap<int> >
       
   193     struct SetHeap
       
   194       : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
       
   195       typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
       
   196       Create;
       
   197     };
       
   198 
       
   199     template <class H, class CR>
       
   200     struct SetStandardHeapTraits : public Traits {
       
   201       typedef CR HeapCrossRef;
       
   202       typedef H Heap;
       
   203       static HeapCrossRef *createHeapCrossRef(int size) {
       
   204         return new HeapCrossRef(size);
       
   205       }
       
   206       static Heap *createHeap(HeapCrossRef &crossref) {
       
   207         return new Heap(crossref);
       
   208       }
       
   209     };
       
   210 
       
   211     /// \brief \ref named-templ-param "Named parameter" for setting
       
   212     /// heap and cross reference type with automatic allocation
       
   213     ///
       
   214     /// \ref named-templ-param "Named parameter" for setting heap and
       
   215     /// cross reference type with automatic allocation. They should
       
   216     /// have standard constructor interfaces to be able to
       
   217     /// automatically created by the algorithm (i.e. the graph should
       
   218     /// be passed to the constructor of the cross reference and the
       
   219     /// cross reference should be passed to the constructor of the
       
   220     /// heap). However, external heap and cross reference objects
       
   221     /// could also be passed to the algorithm using the \ref heap()
       
   222     /// function before calling \ref run() or \ref init(). The heap
       
   223     /// has to maximize the priorities.
       
   224     /// \sa SetHeap
       
   225     template <class H, class CR = RangeMap<int> >
       
   226     struct SetStandardHeap
       
   227       : public NagamochiIbaraki<Graph, CapacityMap,
       
   228                                 SetStandardHeapTraits<H, CR> > {
       
   229       typedef NagamochiIbaraki<Graph, CapacityMap,
       
   230                                SetStandardHeapTraits<H, CR> > Create;
       
   231     };
       
   232 
       
   233     ///@}
       
   234 
       
   235 
       
   236   private:
       
   237 
       
   238     const Graph &_graph;
       
   239     const CapacityMap *_capacity;
       
   240     bool _local_capacity; // unit capacity
       
   241 
       
   242     struct ArcData {
       
   243       typename Graph::Node target;
       
   244       int prev, next;
       
   245     };
       
   246     struct EdgeData {
       
   247       Value capacity;
       
   248       Value cut;
       
   249     };
       
   250 
       
   251     struct NodeData {
       
   252       int first_arc;
       
   253       typename Graph::Node prev, next;
       
   254       int curr_arc;
       
   255       typename Graph::Node last_rep;
       
   256       Value sum;
       
   257     };
       
   258 
       
   259     typename Graph::template NodeMap<NodeData> *_nodes;
       
   260     std::vector<ArcData> _arcs;
       
   261     std::vector<EdgeData> _edges;
       
   262 
       
   263     typename Graph::Node _first_node;
       
   264     int _node_num;
       
   265 
       
   266     Value _min_cut;
       
   267 
       
   268     HeapCrossRef *_heap_cross_ref;
       
   269     bool _local_heap_cross_ref;
       
   270     Heap *_heap;
       
   271     bool _local_heap;
       
   272 
       
   273     typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
       
   274     NodeList *_next_rep;
       
   275 
       
   276     typedef typename Graph::template NodeMap<bool> MinCutMap;
       
   277     MinCutMap *_cut_map;
       
   278 
       
   279     void createStructures() {
       
   280       if (!_nodes) {
       
   281         _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
       
   282       }
       
   283       if (!_capacity) {
       
   284         _local_capacity = true;
       
   285         _capacity = Traits::createCapacityMap(_graph);
       
   286       }
       
   287       if (!_heap_cross_ref) {
       
   288         _local_heap_cross_ref = true;
       
   289         _heap_cross_ref = Traits::createHeapCrossRef(_graph);
       
   290       }
       
   291       if (!_heap) {
       
   292         _local_heap = true;
       
   293         _heap = Traits::createHeap(*_heap_cross_ref);
       
   294       }
       
   295       if (!_next_rep) {
       
   296         _next_rep = new NodeList(_graph);
       
   297       }
       
   298       if (!_cut_map) {
       
   299         _cut_map = new MinCutMap(_graph);
       
   300       }
       
   301     }
       
   302 
       
   303   public :
       
   304 
       
   305     typedef NagamochiIbaraki Create;
       
   306 
       
   307 
       
   308     /// \brief Constructor.
       
   309     ///
       
   310     /// \param graph The graph the algorithm runs on.
       
   311     /// \param capacity The capacity map used by the algorithm.
       
   312     NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
       
   313       : _graph(graph), _capacity(&capacity), _local_capacity(false),
       
   314         _nodes(0), _arcs(), _edges(), _min_cut(),
       
   315         _heap_cross_ref(0), _local_heap_cross_ref(false),
       
   316         _heap(0), _local_heap(false),
       
   317         _next_rep(0), _cut_map(0) {}
       
   318 
       
   319     /// \brief Constructor.
       
   320     ///
       
   321     /// This constructor can be used only when the Traits class
       
   322     /// defines how can the local capacity map be instantiated.
       
   323     /// If the SetUnitCapacity used the algorithm automatically
       
   324     /// constructs the capacity map.
       
   325     ///
       
   326     ///\param graph The graph the algorithm runs on.
       
   327     NagamochiIbaraki(const Graph& graph)
       
   328       : _graph(graph), _capacity(0), _local_capacity(false),
       
   329         _nodes(0), _arcs(), _edges(), _min_cut(),
       
   330         _heap_cross_ref(0), _local_heap_cross_ref(false),
       
   331         _heap(0), _local_heap(false),
       
   332         _next_rep(0), _cut_map(0) {}
       
   333 
       
   334     /// \brief Destructor.
       
   335     ///
       
   336     /// Destructor.
       
   337     ~NagamochiIbaraki() {
       
   338       if (_local_capacity) delete _capacity;
       
   339       if (_nodes) delete _nodes;
       
   340       if (_local_heap) delete _heap;
       
   341       if (_local_heap_cross_ref) delete _heap_cross_ref;
       
   342       if (_next_rep) delete _next_rep;
       
   343       if (_cut_map) delete _cut_map;
       
   344     }
       
   345 
       
   346     /// \brief Sets the heap and the cross reference used by algorithm.
       
   347     ///
       
   348     /// Sets the heap and the cross reference used by algorithm.
       
   349     /// If you don't use this function before calling \ref run(),
       
   350     /// it will allocate one. The destuctor deallocates this
       
   351     /// automatically allocated heap and cross reference, of course.
       
   352     /// \return <tt> (*this) </tt>
       
   353     NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
       
   354     {
       
   355       if (_local_heap_cross_ref) {
       
   356         delete _heap_cross_ref;
       
   357         _local_heap_cross_ref = false;
       
   358       }
       
   359       _heap_cross_ref = &cr;
       
   360       if (_local_heap) {
       
   361         delete _heap;
       
   362         _local_heap = false;
       
   363       }
       
   364       _heap = &hp;
       
   365       return *this;
       
   366     }
       
   367 
       
   368     /// \name Execution control
       
   369     /// The simplest way to execute the algorithm is to use
       
   370     /// one of the member functions called \c run().
       
   371     /// \n
       
   372     /// If you need more control on the execution,
       
   373     /// first you must call \ref init() and then call the start()
       
   374     /// or proper times the processNextPhase() member functions.
       
   375 
       
   376     ///@{
       
   377 
       
   378     /// \brief Initializes the internal data structures.
       
   379     ///
       
   380     /// Initializes the internal data structures.
       
   381     void init() {
       
   382       createStructures();
       
   383 
       
   384       int edge_num = countEdges(_graph);
       
   385       _edges.resize(edge_num);
       
   386       _arcs.resize(2 * edge_num);
       
   387 
       
   388       typename Graph::Node prev = INVALID;
       
   389       _node_num = 0;
       
   390       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
       
   391         (*_cut_map)[n] = false;
       
   392         (*_next_rep)[n] = INVALID;
       
   393         (*_nodes)[n].last_rep = n;
       
   394         (*_nodes)[n].first_arc = -1;
       
   395         (*_nodes)[n].curr_arc = -1;
       
   396         (*_nodes)[n].prev = prev;
       
   397         if (prev != INVALID) {
       
   398           (*_nodes)[prev].next = n;
       
   399         }
       
   400         (*_nodes)[n].next = INVALID;
       
   401         (*_nodes)[n].sum = 0;
       
   402         prev = n;
       
   403         ++_node_num;
       
   404       }
       
   405 
       
   406       _first_node = typename Graph::NodeIt(_graph);
       
   407 
       
   408       int index = 0;
       
   409       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
       
   410         for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
       
   411           typename Graph::Node m = _graph.target(a);
       
   412           
       
   413           if (!(n < m)) continue;
       
   414 
       
   415           (*_nodes)[n].sum += (*_capacity)[a];
       
   416           (*_nodes)[m].sum += (*_capacity)[a];
       
   417           
       
   418           int c = (*_nodes)[m].curr_arc;
       
   419           if (c != -1 && _arcs[c ^ 1].target == n) {
       
   420             _edges[c >> 1].capacity += (*_capacity)[a];
       
   421           } else {
       
   422             _edges[index].capacity = (*_capacity)[a];
       
   423             
       
   424             _arcs[index << 1].prev = -1;
       
   425             if ((*_nodes)[n].first_arc != -1) {
       
   426               _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
       
   427             }
       
   428             _arcs[index << 1].next = (*_nodes)[n].first_arc;
       
   429             (*_nodes)[n].first_arc = (index << 1);
       
   430             _arcs[index << 1].target = m;
       
   431 
       
   432             (*_nodes)[m].curr_arc = (index << 1);
       
   433             
       
   434             _arcs[(index << 1) | 1].prev = -1;
       
   435             if ((*_nodes)[m].first_arc != -1) {
       
   436               _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
       
   437             }
       
   438             _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
       
   439             (*_nodes)[m].first_arc = ((index << 1) | 1);
       
   440             _arcs[(index << 1) | 1].target = n;
       
   441             
       
   442             ++index;
       
   443           }
       
   444         }
       
   445       }
       
   446 
       
   447       typename Graph::Node cut_node = INVALID;
       
   448       _min_cut = std::numeric_limits<Value>::max();
       
   449 
       
   450       for (typename Graph::Node n = _first_node; 
       
   451            n != INVALID; n = (*_nodes)[n].next) {
       
   452         if ((*_nodes)[n].sum < _min_cut) {
       
   453           cut_node = n;
       
   454           _min_cut = (*_nodes)[n].sum;
       
   455         }
       
   456       }
       
   457       (*_cut_map)[cut_node] = true;
       
   458       if (_min_cut == 0) {
       
   459         _first_node = INVALID;
       
   460       }
       
   461     }
       
   462 
       
   463   public:
       
   464 
       
   465     /// \brief Processes the next phase
       
   466     ///
       
   467     /// Processes the next phase in the algorithm. It must be called
       
   468     /// at most one less the number of the nodes in the graph.
       
   469     ///
       
   470     ///\return %True when the algorithm finished.
       
   471     bool processNextPhase() {
       
   472       if (_first_node == INVALID) return true;
       
   473 
       
   474       _heap->clear();
       
   475       for (typename Graph::Node n = _first_node; 
       
   476            n != INVALID; n = (*_nodes)[n].next) {
       
   477         (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
       
   478       }
       
   479 
       
   480       std::vector<typename Graph::Node> order;
       
   481       order.reserve(_node_num);
       
   482       int sep = 0;
       
   483 
       
   484       Value alpha = 0;
       
   485       Value pmc = std::numeric_limits<Value>::max();
       
   486 
       
   487       _heap->push(_first_node, static_cast<Value>(0));
       
   488       while (!_heap->empty()) {
       
   489         typename Graph::Node n = _heap->top();
       
   490         Value v = _heap->prio();
       
   491 
       
   492         _heap->pop();
       
   493         for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
       
   494           switch (_heap->state(_arcs[a].target)) {
       
   495           case Heap::PRE_HEAP: 
       
   496             {
       
   497               Value nv = _edges[a >> 1].capacity;
       
   498               _heap->push(_arcs[a].target, nv);
       
   499               _edges[a >> 1].cut = nv;
       
   500             } break;
       
   501           case Heap::IN_HEAP:
       
   502             {
       
   503               Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
       
   504               _heap->decrease(_arcs[a].target, nv);
       
   505               _edges[a >> 1].cut = nv;
       
   506             } break;
       
   507           case Heap::POST_HEAP:
       
   508             break;
       
   509           }
       
   510         }
       
   511 
       
   512         alpha += (*_nodes)[n].sum;
       
   513         alpha -= 2 * v;
       
   514 
       
   515         order.push_back(n);
       
   516         if (!_heap->empty()) {
       
   517           if (alpha < pmc) {
       
   518             pmc = alpha;
       
   519             sep = order.size();
       
   520           }
       
   521         }
       
   522       }
       
   523 
       
   524       if (static_cast<int>(order.size()) < _node_num) {
       
   525         _first_node = INVALID;
       
   526         for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
       
   527           (*_cut_map)[n] = false;
       
   528         }
       
   529         for (int i = 0; i < static_cast<int>(order.size()); ++i) {
       
   530           typename Graph::Node n = order[i];
       
   531           while (n != INVALID) {
       
   532             (*_cut_map)[n] = true;
       
   533             n = (*_next_rep)[n];
       
   534           }
       
   535         }
       
   536         _min_cut = 0;
       
   537         return true;
       
   538       }
       
   539 
       
   540       if (pmc < _min_cut) {
       
   541         for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
       
   542           (*_cut_map)[n] = false;
       
   543         }
       
   544         for (int i = 0; i < sep; ++i) {
       
   545           typename Graph::Node n = order[i];
       
   546           while (n != INVALID) {
       
   547             (*_cut_map)[n] = true;
       
   548             n = (*_next_rep)[n];
       
   549           }
       
   550         }
       
   551         _min_cut = pmc;
       
   552       }
       
   553 
       
   554       for (typename Graph::Node n = _first_node;
       
   555            n != INVALID; n = (*_nodes)[n].next) {
       
   556         bool merged = false;
       
   557         for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
       
   558           if (!(_edges[a >> 1].cut < pmc)) {
       
   559             if (!merged) {
       
   560               for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
       
   561                 (*_nodes)[_arcs[b].target].curr_arc = b;          
       
   562               }
       
   563               merged = true;
       
   564             }
       
   565             typename Graph::Node m = _arcs[a].target;
       
   566             int nb = 0;
       
   567             for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
       
   568               nb = _arcs[b].next;
       
   569               if ((b ^ a) == 1) continue;
       
   570               typename Graph::Node o = _arcs[b].target;
       
   571               int c = (*_nodes)[o].curr_arc; 
       
   572               if (c != -1 && _arcs[c ^ 1].target == n) {
       
   573                 _edges[c >> 1].capacity += _edges[b >> 1].capacity;
       
   574                 (*_nodes)[n].sum += _edges[b >> 1].capacity;
       
   575                 if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
       
   576                   _edges[b >> 1].cut = _edges[c >> 1].cut;
       
   577                 }
       
   578                 if (_arcs[b ^ 1].prev != -1) {
       
   579                   _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
       
   580                 } else {
       
   581                   (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
       
   582                 }
       
   583                 if (_arcs[b ^ 1].next != -1) {
       
   584                   _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
       
   585                 }
       
   586               } else {
       
   587                 if (_arcs[a].next != -1) {
       
   588                   _arcs[_arcs[a].next].prev = b;
       
   589                 }
       
   590                 _arcs[b].next = _arcs[a].next;
       
   591                 _arcs[b].prev = a;
       
   592                 _arcs[a].next = b;
       
   593                 _arcs[b ^ 1].target = n;
       
   594 
       
   595                 (*_nodes)[n].sum += _edges[b >> 1].capacity;
       
   596                 (*_nodes)[o].curr_arc = b;
       
   597               }
       
   598             }
       
   599 
       
   600             if (_arcs[a].prev != -1) {
       
   601               _arcs[_arcs[a].prev].next = _arcs[a].next;
       
   602             } else {
       
   603               (*_nodes)[n].first_arc = _arcs[a].next;
       
   604             }            
       
   605             if (_arcs[a].next != -1) {
       
   606               _arcs[_arcs[a].next].prev = _arcs[a].prev;
       
   607             }
       
   608 
       
   609             (*_nodes)[n].sum -= _edges[a >> 1].capacity;
       
   610             (*_next_rep)[(*_nodes)[n].last_rep] = m;
       
   611             (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
       
   612             
       
   613             if ((*_nodes)[m].prev != INVALID) {
       
   614               (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
       
   615             } else{
       
   616               _first_node = (*_nodes)[m].next;
       
   617             }
       
   618             if ((*_nodes)[m].next != INVALID) {
       
   619               (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
       
   620             }
       
   621             --_node_num;
       
   622           }
       
   623         }
       
   624       }
       
   625 
       
   626       if (_node_num == 1) {
       
   627         _first_node = INVALID;
       
   628         return true;
       
   629       }
       
   630 
       
   631       return false;
       
   632     }
       
   633 
       
   634     /// \brief Executes the algorithm.
       
   635     ///
       
   636     /// Executes the algorithm.
       
   637     ///
       
   638     /// \pre init() must be called
       
   639     void start() {
       
   640       while (!processNextPhase()) {}
       
   641     }
       
   642 
       
   643 
       
   644     /// \brief Runs %NagamochiIbaraki algorithm.
       
   645     ///
       
   646     /// This method runs the %Min cut algorithm
       
   647     ///
       
   648     /// \note mc.run(s) is just a shortcut of the following code.
       
   649     ///\code
       
   650     ///  mc.init();
       
   651     ///  mc.start();
       
   652     ///\endcode
       
   653     void run() {
       
   654       init();
       
   655       start();
       
   656     }
       
   657 
       
   658     ///@}
       
   659 
       
   660     /// \name Query Functions
       
   661     ///
       
   662     /// The result of the %NagamochiIbaraki
       
   663     /// algorithm can be obtained using these functions.\n
       
   664     /// Before the use of these functions, either run() or start()
       
   665     /// must be called.
       
   666 
       
   667     ///@{
       
   668 
       
   669     /// \brief Returns the min cut value.
       
   670     ///
       
   671     /// Returns the min cut value if the algorithm finished.
       
   672     /// After the first processNextPhase() it is a value of a
       
   673     /// valid cut in the graph.
       
   674     Value minCutValue() const {
       
   675       return _min_cut;
       
   676     }
       
   677 
       
   678     /// \brief Returns a min cut in a NodeMap.
       
   679     ///
       
   680     /// It sets the nodes of one of the two partitions to true and
       
   681     /// the other partition to false.
       
   682     /// \param cutMap A \ref concepts::WriteMap "writable" node map with
       
   683     /// \c bool (or convertible) value type.
       
   684     template <typename CutMap>
       
   685     Value minCutMap(CutMap& cutMap) const {
       
   686       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
       
   687         cutMap.set(n, (*_cut_map)[n]);
       
   688       }
       
   689       return minCutValue();
       
   690     }
       
   691 
       
   692     ///@}
       
   693 
       
   694   };
       
   695 }
       
   696 
       
   697 #endif