| 
	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 
	 |