deba@2284: /* -*- C++ -*-
deba@2284:  *
alpar@2391:  * This file is a part of LEMON, a generic C++ optimization library
alpar@2391:  *
alpar@2553:  * Copyright (C) 2003-2008
alpar@2391:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2284:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2284:  *
deba@2284:  * Permission to use, modify and distribute this software is granted
deba@2284:  * provided that this copyright notice appears in all copies. For
deba@2284:  * precise terms see the accompanying LICENSE file.
deba@2284:  *
deba@2284:  * This software is provided "AS IS" with no warranty of any kind,
deba@2284:  * express or implied, and with no claim as to its suitability for any
deba@2284:  * purpose.
deba@2284:  *
deba@2284:  */
deba@2284: 
deba@2337: #ifndef LEMON_NAGAMOCHI_IBARAKI_H
deba@2337: #define LEMON_NAGAMOCHI_IBARAKI_H
deba@2284: 
deba@2284: 
deba@2376: /// \ingroup min_cut
deba@2337: /// \file 
deba@2337: /// \brief Maximum cardinality search and minimum cut in undirected
deba@2337: /// graphs.
deba@2284: 
deba@2284: #include <lemon/list_graph.h>
deba@2284: #include <lemon/bin_heap.h>
deba@2284: #include <lemon/bucket_heap.h>
deba@2284: 
deba@2337: #include <lemon/unionfind.h>
deba@2337: #include <lemon/topology.h>
deba@2337: 
deba@2284: #include <lemon/bits/invalid.h>
deba@2284: #include <lemon/error.h>
deba@2284: #include <lemon/maps.h>
deba@2284: 
deba@2284: #include <functional>
deba@2284: 
deba@2337: #include <lemon/graph_writer.h>
deba@2337: #include <lemon/time_measure.h>
deba@2337: 
deba@2284: namespace lemon {
deba@2284: 
deba@2284:   namespace _min_cut_bits {
deba@2284: 
deba@2284:     template <typename CapacityMap>
deba@2284:     struct HeapSelector {
deba@2284:       template <typename Value, typename Ref>
deba@2284:       struct Selector {
deba@2284:         typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
deba@2284:       };
deba@2284:     };
deba@2284: 
deba@2284:     template <typename CapacityKey>
deba@2284:     struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
deba@2284:       template <typename Value, typename Ref>
deba@2284:       struct Selector {
deba@2284:         typedef BucketHeap<Ref, false > Heap;
deba@2284:       };
deba@2284:     };
deba@2284: 
deba@2284:   }
deba@2284: 
deba@2284:   /// \brief Default traits class of MaxCardinalitySearch class.
deba@2284:   ///
deba@2284:   /// Default traits class of MaxCardinalitySearch class.
deba@2284:   /// \param Graph Graph type.
deba@2284:   /// \param CapacityMap Type of length map.
deba@2284:   template <typename _Graph, typename _CapacityMap>
deba@2284:   struct MaxCardinalitySearchDefaultTraits {
deba@2284:     /// The graph type the algorithm runs on. 
deba@2284:     typedef _Graph Graph;
deba@2284: 
deba@2284:     /// \brief The type of the map that stores the edge capacities.
deba@2284:     ///
deba@2284:     /// The type of the map that stores the edge capacities.
deba@2284:     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2284:     typedef _CapacityMap CapacityMap;
deba@2284: 
deba@2284:     /// \brief The type of the capacity of the edges.
deba@2284:     typedef typename CapacityMap::Value Value;
deba@2284: 
deba@2284:     /// \brief The cross reference type used by heap.
deba@2284:     ///
deba@2284:     /// The cross reference type used by heap.
deba@2284:     /// Usually it is \c Graph::NodeMap<int>.
deba@2284:     typedef typename Graph::template NodeMap<int> HeapCrossRef;
deba@2284: 
deba@2284:     /// \brief Instantiates a HeapCrossRef.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref HeapCrossRef. 
deba@2284:     /// \param graph is the graph, to which we would like to define the 
deba@2284:     /// HeapCrossRef.
deba@2284:     static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
deba@2284:       return new HeapCrossRef(graph);
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief The heap type used by MaxCardinalitySearch algorithm.
deba@2284:     ///
deba@2284:     /// The heap type used by MaxCardinalitySearch algorithm. It should
deba@2284:     /// maximalize the priorities. The default heap type is
deba@2284:     /// the \ref BinHeap, but it is specialized when the
deba@2284:     /// CapacityMap is ConstMap<Graph::Node, Const<int, 1> >
deba@2284:     /// to BucketHeap.
deba@2284:     ///
deba@2284:     /// \sa MaxCardinalitySearch
deba@2284:     typedef typename _min_cut_bits
deba@2284:     ::HeapSelector<CapacityMap>
deba@2284:     ::template Selector<Value, HeapCrossRef>
deba@2284:     ::Heap Heap;
deba@2284: 
deba@2284:     /// \brief Instantiates a Heap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref Heap. 
deba@2284:     /// \param crossref The cross reference of the heap.
deba@2284:     static Heap *createHeap(HeapCrossRef& crossref) {
deba@2284:       return new Heap(crossref);
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief The type of the map that stores whether a nodes is processed.
deba@2284:     ///
deba@2284:     /// The type of the map that stores whether a nodes is processed.
deba@2284:     /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
deba@2284:     /// By default it is a NullMap.
deba@2284:     typedef NullMap<typename Graph::Node, bool> ProcessedMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a ProcessedMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref ProcessedMap. 
deba@2284:     /// \param graph is the graph, to which
deba@2284:     /// we would like to define the \ref ProcessedMap
deba@2284: #ifdef DOXYGEN
deba@2284:     static ProcessedMap *createProcessedMap(const Graph &graph)
deba@2284: #else
deba@2284:     static ProcessedMap *createProcessedMap(const Graph &)
deba@2284: #endif
deba@2284:     {
deba@2284:       return new ProcessedMap();
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief The type of the map that stores the cardinalties of the nodes.
deba@2284:     /// 
deba@2284:     /// The type of the map that stores the cardinalities of the nodes.
deba@2284:     /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
deba@2284:     typedef typename Graph::template NodeMap<Value> CardinalityMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a CardinalityMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref CardinalityMap. 
deba@2284:     /// \param graph is the graph, to which we would like to define the \ref 
deba@2284:     /// CardinalityMap
deba@2284:     static CardinalityMap *createCardinalityMap(const Graph &graph) {
deba@2284:       return new CardinalityMap(graph);
deba@2284:     }
deba@2284: 
deba@2337: 
deba@2284:   };
deba@2284:   
deba@2376:   /// \ingroup search
deba@2284:   ///
deba@2284:   /// \brief Maximum Cardinality Search algorithm class.
deba@2284:   ///
deba@2284:   /// This class provides an efficient implementation of Maximum Cardinality 
deba@2284:   /// Search algorithm. The maximum cardinality search chooses first time any 
deba@2284:   /// node of the graph. Then every time it chooses the node which is connected
deba@2284:   /// to the processed nodes at most in the sum of capacities on the out 
deba@2284:   /// edges. If there is a cut in the graph the algorithm should choose
deba@2284:   /// again any unprocessed node of the graph. Each node cardinality is
deba@2284:   /// the sum of capacities on the out edges to the nodes which are processed
deba@2284:   /// before the given node.
deba@2284:   ///
deba@2284:   /// The edge capacities are passed to the algorithm using a
deba@2284:   /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 
deba@2284:   /// kind of capacity.
deba@2284:   ///
deba@2284:   /// The type of the capacity is determined by the \ref 
deba@2284:   /// concepts::ReadMap::Value "Value" of the capacity map.
deba@2284:   ///
deba@2284:   /// It is also possible to change the underlying priority heap.
deba@2284:   ///
deba@2284:   ///
deba@2284:   /// \param _Graph The graph type the algorithm runs on. The default value
deba@2284:   /// is \ref ListGraph. The value of Graph is not used directly by
deba@2284:   /// the search algorithm, it is only passed to 
deba@2284:   /// \ref MaxCardinalitySearchDefaultTraits.
deba@2284:   /// \param _CapacityMap This read-only EdgeMap determines the capacities of 
deba@2284:   /// the edges. It is read once for each edge, so the map may involve in
deba@2284:   /// relatively time consuming process to compute the edge capacity if
deba@2284:   /// it is necessary. The default map type is \ref
deba@2284:   /// concepts::Graph::EdgeMap "Graph::EdgeMap<int>".  The value
deba@2284:   /// of CapacityMap is not used directly by search algorithm, it is only 
deba@2284:   /// passed to \ref MaxCardinalitySearchDefaultTraits.  
deba@2284:   /// \param _Traits Traits class to set various data types used by the 
deba@2284:   /// algorithm.  The default traits class is 
deba@2284:   /// \ref MaxCardinalitySearchDefaultTraits 
deba@2284:   /// "MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap>".  
deba@2284:   /// See \ref MaxCardinalitySearchDefaultTraits 
deba@2284:   /// for the documentation of a MaxCardinalitySearch traits class.
deba@2284:   ///
deba@2284:   /// \author Balazs Dezso
deba@2284: 
deba@2284: #ifdef DOXYGEN
deba@2284:   template <typename _Graph, typename _CapacityMap, typename _Traits>
deba@2284: #else
deba@2284:   template <typename _Graph = ListUGraph,
deba@2284: 	    typename _CapacityMap = typename _Graph::template EdgeMap<int>,
deba@2284: 	    typename _Traits = 
deba@2284:             MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap> >
deba@2284: #endif
deba@2284:   class MaxCardinalitySearch {
deba@2284:   public:
deba@2284:     /// \brief \ref Exception for uninitialized parameters.
deba@2284:     ///
deba@2284:     /// This error represents problems in the initialization
deba@2284:     /// of the parameters of the algorithms.
deba@2284:     class UninitializedParameter : public lemon::UninitializedParameter {
deba@2284:     public:
deba@2284:       virtual const char* what() const throw() {
deba@2284: 	return "lemon::MaxCardinalitySearch::UninitializedParameter";
deba@2284:       }
deba@2284:     };
deba@2284: 
deba@2284:     typedef _Traits Traits;
deba@2284:     ///The type of the underlying graph.
deba@2284:     typedef typename Traits::Graph Graph;
deba@2284:     
deba@2284:     ///The type of the capacity of the edges.
deba@2284:     typedef typename Traits::CapacityMap::Value Value;
deba@2284:     ///The type of the map that stores the edge capacities.
deba@2284:     typedef typename Traits::CapacityMap CapacityMap;
deba@2284:     ///The type of the map indicating if a node is processed.
deba@2284:     typedef typename Traits::ProcessedMap ProcessedMap;
deba@2284:     ///The type of the map that stores the cardinalities of the nodes.
deba@2284:     typedef typename Traits::CardinalityMap CardinalityMap;
deba@2284:     ///The cross reference type used for the current heap.
deba@2284:     typedef typename Traits::HeapCrossRef HeapCrossRef;
deba@2284:     ///The heap type used by the algorithm. It maximize the priorities.
deba@2284:     typedef typename Traits::Heap Heap;
deba@2284:   private:
deba@2284:     /// Pointer to the underlying graph.
deba@2284:     const Graph *_graph;
deba@2284:     /// Pointer to the capacity map
deba@2284:     const CapacityMap *_capacity;
deba@2284:     ///Pointer to the map of cardinality.
deba@2284:     CardinalityMap *_cardinality;
deba@2284:     ///Indicates if \ref _cardinality is locally allocated (\c true) or not.
deba@2284:     bool local_cardinality;
deba@2284:     ///Pointer to the map of processed status of the nodes.
deba@2284:     ProcessedMap *_processed;
deba@2284:     ///Indicates if \ref _processed is locally allocated (\c true) or not.
deba@2284:     bool local_processed;
deba@2284:     ///Pointer to the heap cross references.
deba@2284:     HeapCrossRef *_heap_cross_ref;
deba@2284:     ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
deba@2284:     bool local_heap_cross_ref;
deba@2284:     ///Pointer to the heap.
deba@2284:     Heap *_heap;
deba@2284:     ///Indicates if \ref _heap is locally allocated (\c true) or not.
deba@2284:     bool local_heap;
deba@2284: 
deba@2284:   public :
deba@2284: 
deba@2284:     typedef MaxCardinalitySearch Create;
deba@2284:  
deba@2284:     ///\name Named template parameters
deba@2284: 
deba@2284:     ///@{
deba@2284: 
deba@2284:     template <class T>
deba@2284:     struct DefCardinalityMapTraits : public Traits {
deba@2284:       typedef T CardinalityMap;
deba@2284:       static CardinalityMap *createCardinalityMap(const Graph &) 
deba@2284:       {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:     };
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting 
deba@2284:     /// CardinalityMap type
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting CardinalityMap 
deba@2284:     /// type
deba@2284:     template <class T>
deba@2284:     struct DefCardinalityMap 
deba@2284:       : public MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                     DefCardinalityMapTraits<T> > { 
deba@2284:       typedef MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                    DefCardinalityMapTraits<T> > Create;
deba@2284:     };
deba@2284:     
deba@2284:     template <class T>
deba@2284:     struct DefProcessedMapTraits : public Traits {
deba@2284:       typedef T ProcessedMap;
deba@2284:       static ProcessedMap *createProcessedMap(const Graph &) {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:     };
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting 
deba@2284:     /// ProcessedMap type
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
deba@2284:     ///
deba@2284:     template <class T>
deba@2284:     struct DefProcessedMap 
deba@2284:       : public MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                     DefProcessedMapTraits<T> > { 
deba@2284:       typedef MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                    DefProcessedMapTraits<T> > Create;
deba@2284:     };
deba@2284:     
deba@2284:     template <class H, class CR>
deba@2284:     struct DefHeapTraits : public Traits {
deba@2284:       typedef CR HeapCrossRef;
deba@2284:       typedef H Heap;
deba@2284:       static HeapCrossRef *createHeapCrossRef(const Graph &) {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:       static Heap *createHeap(HeapCrossRef &) {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:     };
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting heap 
deba@2284:     /// and cross reference type
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting heap and cross 
deba@2284:     /// reference type
deba@2284:     template <class H, class CR = typename Graph::template NodeMap<int> >
deba@2284:     struct DefHeap
deba@2284:       : public MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                     DefHeapTraits<H, CR> > { 
deba@2284:       typedef MaxCardinalitySearch< Graph, CapacityMap, 
deba@2284:                                     DefHeapTraits<H, CR> > Create;
deba@2284:     };
deba@2284: 
deba@2284:     template <class H, class CR>
deba@2284:     struct DefStandardHeapTraits : public Traits {
deba@2284:       typedef CR HeapCrossRef;
deba@2284:       typedef H Heap;
deba@2284:       static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
deba@2284: 	return new HeapCrossRef(graph);
deba@2284:       }
deba@2284:       static Heap *createHeap(HeapCrossRef &crossref) {
deba@2284: 	return new Heap(crossref);
deba@2284:       }
deba@2284:     };
deba@2284: 
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting heap and 
deba@2284:     /// cross reference type with automatic allocation
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting heap and cross 
deba@2284:     /// reference type. It can allocate the heap and the cross reference 
deba@2284:     /// object if the cross reference's constructor waits for the graph as 
deba@2284:     /// parameter and the heap's constructor waits for the cross reference.
deba@2284:     template <class H, class CR = typename Graph::template NodeMap<int> >
deba@2284:     struct DefStandardHeap
deba@2284:       : public MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                     DefStandardHeapTraits<H, CR> > { 
deba@2284:       typedef MaxCardinalitySearch<Graph, CapacityMap, 
deba@2284:                                    DefStandardHeapTraits<H, CR> > 
deba@2284:       Create;
deba@2284:     };
deba@2284:     
deba@2284:     ///@}
deba@2284: 
deba@2284: 
deba@2284:   protected:
deba@2284: 
deba@2284:     MaxCardinalitySearch() {}
deba@2284: 
deba@2284:   public:      
deba@2284:     
deba@2284:     /// \brief Constructor.
deba@2284:     ///
deba@2284:     ///\param graph the graph the algorithm will run on.
deba@2284:     ///\param capacity the capacity map used by the algorithm.
deba@2284:     MaxCardinalitySearch(const Graph& graph, const CapacityMap& capacity) :
deba@2284:       _graph(&graph), _capacity(&capacity),
deba@2284:       _cardinality(0), local_cardinality(false),
deba@2284:       _processed(0), local_processed(false),
deba@2284:       _heap_cross_ref(0), local_heap_cross_ref(false),
deba@2284:       _heap(0), local_heap(false)
deba@2284:     { }
deba@2284:     
deba@2284:     /// \brief Destructor.
deba@2284:     ~MaxCardinalitySearch() {
deba@2284:       if(local_cardinality) delete _cardinality;
deba@2284:       if(local_processed) delete _processed;
deba@2284:       if(local_heap_cross_ref) delete _heap_cross_ref;
deba@2284:       if(local_heap) delete _heap;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the capacity map.
deba@2284:     ///
deba@2284:     /// Sets the capacity map.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2284:     MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
deba@2284:       _capacity = &m;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the map storing the cardinalities calculated by the 
deba@2284:     /// algorithm.
deba@2284:     ///
deba@2284:     /// Sets the map storing the cardinalities calculated by the algorithm.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated map, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2284:     MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
deba@2284:       if(local_cardinality) {
deba@2284: 	delete _cardinality;
deba@2284: 	local_cardinality=false;
deba@2284:       }
deba@2284:       _cardinality = &m;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the map storing the processed nodes.
deba@2284:     ///
deba@2284:     /// Sets the map storing the processed nodes.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated map, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2284:     MaxCardinalitySearch &processedMap(ProcessedMap &m) 
deba@2284:     {
deba@2284:       if(local_processed) {
deba@2284: 	delete _processed;
deba@2284: 	local_processed=false;
deba@2284:       }
deba@2284:       _processed = &m;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the heap and the cross reference used by algorithm.
deba@2284:     ///
deba@2284:     /// Sets the heap and the cross reference used by algorithm.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated map, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2386:     MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
deba@2284:       if(local_heap_cross_ref) {
deba@2284: 	delete _heap_cross_ref;
deba@2284: 	local_heap_cross_ref = false;
deba@2284:       }
deba@2386:       _heap_cross_ref = &cr;
deba@2284:       if(local_heap) {
deba@2284: 	delete _heap;
deba@2284: 	local_heap = false;
deba@2284:       }
deba@2386:       _heap = &hp;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:   private:
deba@2284: 
deba@2284:     typedef typename Graph::Node Node;
deba@2284:     typedef typename Graph::NodeIt NodeIt;
deba@2284:     typedef typename Graph::Edge Edge;
deba@2284:     typedef typename Graph::InEdgeIt InEdgeIt;
deba@2284: 
deba@2284:     void create_maps() {
deba@2284:       if(!_cardinality) {
deba@2284: 	local_cardinality = true;
deba@2284: 	_cardinality = Traits::createCardinalityMap(*_graph);
deba@2284:       }
deba@2284:       if(!_processed) {
deba@2284: 	local_processed = true;
deba@2284: 	_processed = Traits::createProcessedMap(*_graph);
deba@2284:       }
deba@2284:       if (!_heap_cross_ref) {
deba@2284: 	local_heap_cross_ref = true;
deba@2284: 	_heap_cross_ref = Traits::createHeapCrossRef(*_graph);
deba@2284:       }
deba@2284:       if (!_heap) {
deba@2284: 	local_heap = true;
deba@2284: 	_heap = Traits::createHeap(*_heap_cross_ref);
deba@2284:       }
deba@2284:     }
deba@2284:     
deba@2284:     void finalizeNodeData(Node node, Value capacity) {
deba@2284:       _processed->set(node, true);
deba@2284:       _cardinality->set(node, capacity);
deba@2284:     }
deba@2284: 
deba@2284:   public:
deba@2284:     /// \name Execution control
deba@2284:     /// The simplest way to execute the algorithm is to use
deba@2284:     /// one of the member functions called \c run(...).
deba@2284:     /// \n
deba@2284:     /// If you need more control on the execution,
deba@2284:     /// first you must call \ref init(), then you can add several source nodes
deba@2284:     /// with \ref addSource().
deba@2284:     /// Finally \ref start() will perform the actual path
deba@2284:     /// computation.
deba@2284: 
deba@2284:     ///@{
deba@2284: 
deba@2284:     /// \brief Initializes the internal data structures.
deba@2284:     ///
deba@2284:     /// Initializes the internal data structures.
deba@2284:     void init() {
deba@2284:       create_maps();
deba@2284:       _heap->clear();
deba@2284:       for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
deba@2284: 	_processed->set(it, false);
deba@2284: 	_heap_cross_ref->set(it, Heap::PRE_HEAP);
deba@2284:       }
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief Adds a new source node.
deba@2284:     /// 
deba@2284:     /// Adds a new source node to the priority heap.
deba@2284:     ///
deba@2284:     /// It checks if the node has not yet been added to the heap.
deba@2284:     void addSource(Node source, Value capacity = 0) {
deba@2284:       if(_heap->state(source) == Heap::PRE_HEAP) {
deba@2284: 	_heap->push(source, capacity);
deba@2284:       } 
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief Processes the next node in the priority heap
deba@2284:     ///
deba@2284:     /// Processes the next node in the priority heap.
deba@2284:     ///
deba@2284:     /// \return The processed node.
deba@2284:     ///
deba@2284:     /// \warning The priority heap must not be empty!
deba@2284:     Node processNextNode() {
deba@2284:       Node node = _heap->top(); 
deba@2284:       finalizeNodeData(node, _heap->prio());
deba@2284:       _heap->pop();
deba@2284:       
deba@2284:       for (InEdgeIt it(*_graph, node); it != INVALID; ++it) {
deba@2284: 	Node source = _graph->source(it); 
deba@2284: 	switch (_heap->state(source)) {
deba@2284: 	case Heap::PRE_HEAP:
deba@2284: 	  _heap->push(source, (*_capacity)[it]); 
deba@2284: 	  break;
deba@2284: 	case Heap::IN_HEAP:
deba@2284: 	  _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]); 
deba@2284: 	  break;
deba@2284: 	case Heap::POST_HEAP:
deba@2284: 	  break;
deba@2284: 	}
deba@2284:       }
deba@2284:       return node;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Next node to be processed.
deba@2284:     ///
deba@2284:     /// Next node to be processed.
deba@2284:     ///
deba@2284:     /// \return The next node to be processed or INVALID if the 
deba@2284:     /// priority heap is empty.
deba@2284:     Node nextNode() { 
deba@2284:       return _heap->empty() ? _heap->top() : INVALID;
deba@2284:     }
deba@2284:  
deba@2284:     /// \brief Returns \c false if there are nodes
deba@2284:     /// to be processed in the priority heap
deba@2284:     ///
deba@2284:     /// Returns \c false if there are nodes
deba@2284:     /// to be processed in the priority heap
deba@2284:     bool emptyQueue() { return _heap->empty(); }
deba@2284:     /// \brief Returns the number of the nodes to be processed 
deba@2284:     /// in the priority heap
deba@2284:     ///
deba@2284:     /// Returns the number of the nodes to be processed in the priority heap
deba@2284:     int queueSize() { return _heap->size(); }
deba@2284:     
deba@2284:     /// \brief Executes the algorithm.
deba@2284:     ///
deba@2284:     /// Executes the algorithm.
deba@2284:     ///
deba@2284:     ///\pre init() must be called and at least one node should be added
deba@2284:     /// with addSource() before using this function.
deba@2284:     ///
deba@2284:     /// This method runs the Maximum Cardinality Search algorithm from the 
deba@2284:     /// source node(s).
deba@2284:     void start() {
deba@2284:       while ( !_heap->empty() ) processNextNode();
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief Executes the algorithm until \c dest is reached.
deba@2284:     ///
deba@2284:     /// Executes the algorithm until \c dest is reached.
deba@2284:     ///
deba@2284:     /// \pre init() must be called and at least one node should be added
deba@2284:     /// with addSource() before using this function.
deba@2284:     ///
deba@2284:     /// This method runs the %MaxCardinalitySearch algorithm from the source 
deba@2284:     /// nodes.
deba@2284:     void start(Node dest) {
deba@2284:       while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
deba@2284:       if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief Executes the algorithm until a condition is met.
deba@2284:     ///
deba@2284:     /// Executes the algorithm until a condition is met.
deba@2284:     ///
deba@2284:     /// \pre init() must be called and at least one node should be added
deba@2284:     /// with addSource() before using this function.
deba@2284:     ///
deba@2284:     /// \param nm must be a bool (or convertible) node map. The algorithm
deba@2284:     /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
deba@2284:     template <typename NodeBoolMap>
deba@2284:     void start(const NodeBoolMap &nm) {
deba@2284:       while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
deba@2284:       if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief Runs the maximal cardinality search algorithm from node \c s.
deba@2284:     ///
deba@2284:     /// This method runs the %MaxCardinalitySearch algorithm from a root 
deba@2284:     /// node \c s.
deba@2284:     ///
deba@2284:     ///\note d.run(s) is just a shortcut of the following code.
deba@2284:     ///\code
deba@2284:     ///  d.init();
deba@2284:     ///  d.addSource(s);
deba@2284:     ///  d.start();
deba@2284:     ///\endcode
deba@2284:     void run(Node s) {
deba@2284:       init();
deba@2284:       addSource(s);
deba@2284:       start();
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Runs the maximal cardinality search algorithm for the 
deba@2284:     /// whole graph.
deba@2284:     ///
deba@2284:     /// This method runs the %MaxCardinalitySearch algorithm from all 
deba@2284:     /// unprocessed node of the graph.
deba@2284:     ///
deba@2284:     ///\note d.run(s) is just a shortcut of the following code.
deba@2284:     ///\code
deba@2284:     ///  d.init();
deba@2284:     ///  for (NodeIt it(graph); it != INVALID; ++it) {
deba@2284:     ///    if (!d.reached(it)) {
deba@2284:     ///      d.addSource(s);
deba@2284:     ///      d.start();
deba@2284:     ///    }
deba@2284:     ///  }
deba@2284:     ///\endcode
deba@2284:     void run() {
deba@2284:       init();
deba@2284:       for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2284:         if (!reached(it)) {
deba@2284:           addSource(it);
deba@2284:           start();
deba@2284:         }
deba@2284:       }
deba@2284:     }
deba@2284:     
deba@2284:     ///@}
deba@2284: 
deba@2284:     /// \name Query Functions
deba@2284:     /// The result of the maximum cardinality search algorithm can be 
deba@2284:     /// obtained using these functions.
deba@2284:     /// \n
deba@2284:     /// Before the use of these functions, either run() or start() must be 
deba@2284:     /// called.
deba@2284:     
deba@2284:     ///@{
deba@2284: 
deba@2284:     /// \brief The cardinality of a node.
deba@2284:     ///
deba@2284:     /// Returns the cardinality of a node.
deba@2284:     /// \pre \ref run() must be called before using this function.
deba@2284:     /// \warning If node \c v in unreachable from the root the return value
deba@2284:     /// of this funcion is undefined.
deba@2284:     Value cardinality(Node node) const { return (*_cardinality)[node]; }
deba@2284: 
deba@2337:     /// \brief The current cardinality of a node.
deba@2337:     ///
deba@2337:     /// Returns the current cardinality of a node.
deba@2337:     /// \pre the given node should be reached but not processed
deba@2337:     Value currentCardinality(Node node) const { return (*_heap)[node]; }
deba@2337: 
deba@2284:     /// \brief Returns a reference to the NodeMap of cardinalities.
deba@2284:     ///
deba@2284:     /// Returns a reference to the NodeMap of cardinalities. \pre \ref run() 
deba@2284:     /// must be called before using this function.
deba@2284:     const CardinalityMap &cardinalityMap() const { return *_cardinality;}
deba@2284:  
deba@2284:     /// \brief Checks if a node is reachable from the root.
deba@2284:     ///
deba@2284:     /// Returns \c true if \c v is reachable from the root.
deba@2284:     /// \warning The source nodes are inditated as unreached.
deba@2284:     /// \pre \ref run() must be called before using this function.
deba@2284:     bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
deba@2284: 
deba@2284:     /// \brief Checks if a node is processed.
deba@2284:     ///
deba@2284:     /// Returns \c true if \c v is processed, i.e. the shortest
deba@2284:     /// path to \c v has already found.
deba@2284:     /// \pre \ref run() must be called before using this function.
deba@2284:     bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
deba@2284:     
deba@2284:     ///@}
deba@2284:   };
deba@2284: 
deba@2284:   /// \brief Default traits class of NagamochiIbaraki class.
deba@2284:   ///
deba@2284:   /// Default traits class of NagamochiIbaraki class.
deba@2284:   /// \param Graph Graph type.
deba@2284:   /// \param CapacityMap Type of length map.
deba@2284:   template <typename _Graph, typename _CapacityMap>
deba@2284:   struct NagamochiIbarakiDefaultTraits {
deba@2284:     /// \brief The type of the capacity of the edges.
deba@2284:     typedef typename _CapacityMap::Value Value;
deba@2284: 
deba@2284:     /// The graph type the algorithm runs on. 
deba@2284:     typedef _Graph Graph;
deba@2284: 
deba@2284:     /// The AuxGraph type which is an Graph
deba@2284:     typedef ListUGraph AuxGraph;
deba@2284: 
deba@2284:     /// \brief Instantiates a AuxGraph.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref AuxGraph. 
deba@2284:     static AuxGraph *createAuxGraph() {
deba@2284:       return new AuxGraph();
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief The type of the map that stores the edge capacities.
deba@2284:     ///
deba@2284:     /// The type of the map that stores the edge capacities.
deba@2284:     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2284:     typedef _CapacityMap CapacityMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a CapacityMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref CapacityMap.
deba@2284: #ifdef DOXYGEN
deba@2284:     static CapacityMap *createCapacityMap(const Graph& graph) 
deba@2284: #else
deba@2284:     static CapacityMap *createCapacityMap(const Graph&)
deba@2284: #endif
deba@2284:     {
deba@2284:       throw UninitializedParameter();
deba@2284:     }
deba@2284: 
deba@2337:     /// \brief The CutValueMap type
deba@2337:     ///
deba@2337:     /// The type of the map that stores the cut value of a node.
deba@2337:     typedef AuxGraph::NodeMap<Value> AuxCutValueMap;
deba@2337: 
deba@2337:     /// \brief Instantiates a AuxCutValueMap.
deba@2337:     ///
deba@2337:     /// This function instantiates a \ref AuxCutValueMap. 
deba@2337:     static AuxCutValueMap *createAuxCutValueMap(const AuxGraph& graph) {
deba@2337:       return new AuxCutValueMap(graph);
deba@2337:     }
deba@2337: 
deba@2284:     /// \brief The AuxCapacityMap type
deba@2284:     ///
deba@2337:     /// The type of the map that stores the auxiliary edge capacities.
deba@2284:     typedef AuxGraph::UEdgeMap<Value> AuxCapacityMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a AuxCapacityMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref AuxCapacityMap. 
deba@2284:     static AuxCapacityMap *createAuxCapacityMap(const AuxGraph& graph) {
deba@2284:       return new AuxCapacityMap(graph);
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief The cross reference type used by heap.
deba@2284:     ///
deba@2284:     /// The cross reference type used by heap.
deba@2284:     /// Usually it is \c Graph::NodeMap<int>.
deba@2284:     typedef AuxGraph::NodeMap<int> HeapCrossRef;
deba@2284: 
deba@2284:     /// \brief Instantiates a HeapCrossRef.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref HeapCrossRef. 
deba@2284:     /// \param graph is the graph, to which we would like to define the 
deba@2284:     /// HeapCrossRef.
deba@2284:     static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
deba@2284:       return new HeapCrossRef(graph);
deba@2284:     }
deba@2284:     
deba@2284:     /// \brief The heap type used by NagamochiIbaraki algorithm.
deba@2284:     ///
deba@2284:     /// The heap type used by NagamochiIbaraki algorithm. It should
deba@2284:     /// maximalize the priorities and the heap's key type is
deba@2284:     /// the aux graph's node.
deba@2284:     ///
deba@2284:     /// \sa BinHeap
deba@2284:     /// \sa NagamochiIbaraki
deba@2284:     typedef typename _min_cut_bits
deba@2284:     ::HeapSelector<CapacityMap>
deba@2284:     ::template Selector<Value, HeapCrossRef>
deba@2284:     ::Heap Heap;
deba@2284:     
deba@2284:     /// \brief Instantiates a Heap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref Heap. 
deba@2284:     /// \param crossref The cross reference of the heap.
deba@2284:     static Heap *createHeap(HeapCrossRef& crossref) {
deba@2284:       return new Heap(crossref);
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Map from the AuxGraph's node type to the Graph's node type.
deba@2284:     ///
deba@2284:     /// Map from the AuxGraph's node type to the Graph's node type.
deba@2284:     typedef typename AuxGraph
deba@2284:     ::template NodeMap<typename Graph::Node> NodeRefMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a NodeRefMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref NodeRefMap. 
deba@2284:     static NodeRefMap *createNodeRefMap(const AuxGraph& graph) {
deba@2284:       return new NodeRefMap(graph);
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Map from the Graph's node type to the Graph's node type.
deba@2284:     ///
deba@2284:     /// Map from the Graph's node type to the Graph's node type.
deba@2284:     typedef typename Graph
deba@2284:     ::template NodeMap<typename Graph::Node> ListRefMap;
deba@2284: 
deba@2284:     /// \brief Instantiates a ListRefMap.
deba@2284:     ///
deba@2284:     /// This function instantiates a \ref ListRefMap. 
deba@2284:     static ListRefMap *createListRefMap(const Graph& graph) {
deba@2284:       return new ListRefMap(graph);
deba@2284:     }
deba@2284:     
deba@2284: 
deba@2284:   };
deba@2284: 
deba@2376:   /// \ingroup min_cut
deba@2284:   ///
deba@2284:   /// \brief Calculates the minimum cut in an undirected graph.
deba@2284:   ///
deba@2284:   /// Calculates the minimum cut in an undirected graph with the
deba@2284:   /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
deba@2284:   /// nodes into two partitions with the minimum sum of edge capacities
deba@2284:   /// between the two partitions. The algorithm can be used to test
deba@2284:   /// the network reliability specifically to test how many links have
deba@2284:   /// to be destroyed in the network to split it at least two
deba@2284:   /// distinict subnetwork.
deba@2284:   ///
deba@2284:   /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with
deba@2530:   /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
deba@2530:   /// When unit capacity minimum cut is computed then it uses
deba@2530:   /// BucketHeap which results \f$ O(ne) \f$ time complexity.
deba@2337:   ///
deba@2337:   /// \warning The value type of the capacity map should be able to hold
deba@2337:   /// any cut value of the graph, otherwise the result can overflow.
deba@2284: #ifdef DOXYGEN
deba@2284:   template <typename _Graph, typename _CapacityMap, typename _Traits>
deba@2284: #else
deba@2284:   template <typename _Graph = ListUGraph, 
deba@2284: 	    typename _CapacityMap = typename _Graph::template UEdgeMap<int>, 
deba@2284: 	    typename _Traits 
deba@2284:             = NagamochiIbarakiDefaultTraits<_Graph, _CapacityMap> >
deba@2284: #endif
deba@2284:   class NagamochiIbaraki {
deba@2284:   public:
deba@2284:     /// \brief \ref Exception for uninitialized parameters.
deba@2284:     ///
deba@2284:     /// This error represents problems in the initialization
deba@2284:     /// of the parameters of the algorithms.
deba@2284:     class UninitializedParameter : public lemon::UninitializedParameter {
deba@2284:     public:
deba@2284:       virtual const char* what() const throw() {
deba@2284: 	return "lemon::NagamochiIbaraki::UninitializedParameter";
deba@2284:       }
deba@2284:     };
deba@2284: 
deba@2284: 
deba@2284:   private:
deba@2284: 
deba@2284:     typedef _Traits Traits;
deba@2284:     /// The type of the underlying graph.
deba@2284:     typedef typename Traits::Graph Graph;
deba@2284:     
deba@2284:     /// The type of the capacity of the edges.
deba@2284:     typedef typename Traits::CapacityMap::Value Value;
deba@2284:     /// The type of the map that stores the edge capacities.
deba@2284:     typedef typename Traits::CapacityMap CapacityMap;
deba@2284:     /// The type of the aux graph
deba@2284:     typedef typename Traits::AuxGraph AuxGraph;
deba@2284:     /// The type of the aux capacity map
deba@2284:     typedef typename Traits::AuxCapacityMap AuxCapacityMap;
deba@2337:     /// The type of the aux cut value map
deba@2337:     typedef typename Traits::AuxCutValueMap AuxCutValueMap;
deba@2284:     /// The cross reference type used for the current heap.
deba@2284:     typedef typename Traits::HeapCrossRef HeapCrossRef;
deba@2284:     /// The heap type used by the max cardinality algorithm.
deba@2284:     typedef typename Traits::Heap Heap;
deba@2284:     /// The node refrefernces between the original and aux graph type.
deba@2284:     typedef typename Traits::NodeRefMap NodeRefMap;
deba@2284:     /// The list node refrefernces in the original graph type.
deba@2284:     typedef typename Traits::ListRefMap ListRefMap;
deba@2284: 
deba@2284:   public:
deba@2284: 
deba@2284:     ///\name Named template parameters
deba@2284: 
deba@2284:     ///@{
deba@2284: 
deba@2530:     struct DefUnitCapacityTraits : public Traits {
deba@2284:       typedef ConstMap<typename Graph::UEdge, Const<int, 1> > CapacityMap;
deba@2284:       static CapacityMap *createCapacityMap(const Graph&) {
deba@2284: 	return new CapacityMap();
deba@2284:       }
deba@2284:     };
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting  
deba@2284:     /// the capacity type to constMap<UEdge, int, 1>()
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting 
deba@2284:     /// the capacity type to constMap<UEdge, int, 1>()
deba@2530:     struct DefUnitCapacity
deba@2284:       : public NagamochiIbaraki<Graph, CapacityMap, 
deba@2530:                                 DefUnitCapacityTraits> { 
deba@2284:       typedef NagamochiIbaraki<Graph, CapacityMap, 
deba@2530:                                DefUnitCapacityTraits> Create;
deba@2284:     };
deba@2284: 
deba@2284: 
deba@2284:     template <class H, class CR>
deba@2284:     struct DefHeapTraits : public Traits {
deba@2284:       typedef CR HeapCrossRef;
deba@2284:       typedef H Heap;
deba@2284:       static HeapCrossRef *createHeapCrossRef(const AuxGraph &) {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:       static Heap *createHeap(HeapCrossRef &) {
deba@2284: 	throw UninitializedParameter();
deba@2284:       }
deba@2284:     };
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting heap 
deba@2284:     /// and cross reference type
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting heap and cross 
deba@2284:     /// reference type
deba@2284:     template <class H, class CR = typename Graph::template NodeMap<int> >
deba@2284:     struct DefHeap
deba@2284:       : public NagamochiIbaraki<Graph, CapacityMap, 
deba@2284:                                 DefHeapTraits<H, CR> > { 
deba@2284:       typedef NagamochiIbaraki< Graph, CapacityMap, 
deba@2284:                                 DefHeapTraits<H, CR> > Create;
deba@2284:     };
deba@2284: 
deba@2284:     template <class H, class CR>
deba@2284:     struct DefStandardHeapTraits : public Traits {
deba@2284:       typedef CR HeapCrossRef;
deba@2284:       typedef H Heap;
deba@2284:       static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
deba@2284: 	return new HeapCrossRef(graph);
deba@2284:       }
deba@2284:       static Heap *createHeap(HeapCrossRef &crossref) {
deba@2284: 	return new Heap(crossref);
deba@2284:       }
deba@2284:     };
deba@2284: 
deba@2284:     /// \brief \ref named-templ-param "Named parameter" for setting heap and 
deba@2284:     /// cross reference type with automatic allocation
deba@2284:     ///
deba@2284:     /// \ref named-templ-param "Named parameter" for setting heap and cross 
deba@2284:     /// reference type. It can allocate the heap and the cross reference 
deba@2284:     /// object if the cross reference's constructor waits for the graph as 
deba@2284:     /// parameter and the heap's constructor waits for the cross reference.
deba@2284:     template <class H, class CR = typename Graph::template NodeMap<int> >
deba@2284:     struct DefStandardHeap
deba@2284:       : public NagamochiIbaraki<Graph, CapacityMap, 
deba@2284:                                 DefStandardHeapTraits<H, CR> > { 
deba@2284:       typedef NagamochiIbaraki<Graph, CapacityMap, 
deba@2284:                                DefStandardHeapTraits<H, CR> > 
deba@2284:       Create;
deba@2284:     };
deba@2284: 
deba@2284:     ///@}
deba@2284: 
deba@2284: 
deba@2284:   private:
deba@2284:     /// Pointer to the underlying graph.
deba@2284:     const Graph *_graph;
deba@2284:     /// Pointer to the capacity map
deba@2284:     const CapacityMap *_capacity;
deba@2284:     /// \brief Indicates if \ref _capacity is locally allocated 
deba@2284:     /// (\c true) or not.
deba@2284:     bool local_capacity;
deba@2284: 
deba@2284:     /// Pointer to the aux graph.
deba@2284:     AuxGraph *_aux_graph;
deba@2284:     /// \brief Indicates if \ref _aux_graph is locally allocated 
deba@2284:     /// (\c true) or not.
deba@2284:     bool local_aux_graph;
deba@2284:     /// Pointer to the aux capacity map
deba@2284:     AuxCapacityMap *_aux_capacity;
deba@2284:     /// \brief Indicates if \ref _aux_capacity is locally allocated 
deba@2284:     /// (\c true) or not.
deba@2284:     bool local_aux_capacity;
deba@2337:     /// Pointer to the aux cut value map
deba@2337:     AuxCutValueMap *_aux_cut_value;
deba@2337:     /// \brief Indicates if \ref _aux_cut_value is locally allocated 
deba@2337:     /// (\c true) or not.
deba@2337:     bool local_aux_cut_value;
deba@2284:     /// Pointer to the heap cross references.
deba@2284:     HeapCrossRef *_heap_cross_ref;
deba@2284:     /// \brief Indicates if \ref _heap_cross_ref is locally allocated 
deba@2284:     /// (\c true) or not.
deba@2284:     bool local_heap_cross_ref;
deba@2284:     /// Pointer to the heap.
deba@2284:     Heap *_heap;
deba@2284:     /// Indicates if \ref _heap is locally allocated (\c true) or not.
deba@2284:     bool local_heap;
deba@2284: 
deba@2284:     /// The min cut value.
deba@2284:     Value _min_cut;
deba@2284:     /// The number of the nodes of the aux graph.
deba@2284:     int _node_num;
deba@2337:     /// The first and last node of the min cut in the next list.
deba@2337:     std::vector<typename Graph::Node> _cut;
deba@2284: 
deba@2284:     /// \brief The first and last element in the list associated
deba@2284:     /// to the aux graph node.
deba@2284:     NodeRefMap *_first, *_last;
deba@2284:     /// \brief The next node in the node lists.
deba@2284:     ListRefMap *_next;
deba@2284:     
deba@2337:     void createStructures() {
deba@2284:       if (!_capacity) {
deba@2284:         local_capacity = true;
deba@2284:         _capacity = Traits::createCapacityMap(*_graph);
deba@2284:       }
deba@2284:       if(!_aux_graph) {
deba@2284: 	local_aux_graph = true;
deba@2284: 	_aux_graph = Traits::createAuxGraph();
deba@2284:       }
deba@2284:       if(!_aux_capacity) {
deba@2284: 	local_aux_capacity = true;
deba@2284: 	_aux_capacity = Traits::createAuxCapacityMap(*_aux_graph);
deba@2284:       }
deba@2337:       if(!_aux_cut_value) {
deba@2337: 	local_aux_cut_value = true;
deba@2337: 	_aux_cut_value = Traits::createAuxCutValueMap(*_aux_graph);
deba@2337:       }
deba@2284: 
deba@2284:       _first = Traits::createNodeRefMap(*_aux_graph);
deba@2284:       _last = Traits::createNodeRefMap(*_aux_graph);
deba@2284: 
deba@2284:       _next = Traits::createListRefMap(*_graph);
deba@2284: 
deba@2284:       if (!_heap_cross_ref) {
deba@2284: 	local_heap_cross_ref = true;
deba@2284: 	_heap_cross_ref = Traits::createHeapCrossRef(*_aux_graph);
deba@2284:       }
deba@2284:       if (!_heap) {
deba@2284: 	local_heap = true;
deba@2284: 	_heap = Traits::createHeap(*_heap_cross_ref);
deba@2284:       }
deba@2284:     }
deba@2284: 
deba@2337:     void createAuxGraph() {
deba@2337:       typename Graph::template NodeMap<typename AuxGraph::Node> ref(*_graph);
deba@2337: 
deba@2337:       for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
deba@2337:         _next->set(n, INVALID);
deba@2337:         typename AuxGraph::Node node = _aux_graph->addNode();
deba@2337:         _first->set(node, n);
deba@2337:         _last->set(node, n);
deba@2337:         ref.set(n, node);
deba@2337:       }
deba@2337: 
deba@2337:       typename AuxGraph::template NodeMap<typename AuxGraph::UEdge> 
deba@2337:       edges(*_aux_graph, INVALID);
deba@2337: 
deba@2337:       for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
deba@2337:         for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
deba@2337:           typename Graph::Node tn = _graph->runningNode(e);
deba@2337:           if (n < tn || n == tn) continue;
deba@2337:           if (edges[ref[tn]] != INVALID) {
deba@2337:             Value value = 
deba@2337:               (*_aux_capacity)[edges[ref[tn]]] + (*_capacity)[e];
deba@2337:             _aux_capacity->set(edges[ref[tn]], value);
deba@2337:           } else {
deba@2337:             edges.set(ref[tn], _aux_graph->addEdge(ref[n], ref[tn]));
deba@2337:             Value value = (*_capacity)[e];
deba@2337:             _aux_capacity->set(edges[ref[tn]], value);            
deba@2337:           }
deba@2337:         }
deba@2337:         for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
deba@2337:           typename Graph::Node tn = _graph->runningNode(e);
deba@2337:           edges.set(ref[tn], INVALID);
deba@2337:         }
deba@2337:       }
deba@2337: 
deba@2337:       _cut.resize(1, INVALID);
deba@2337:       _min_cut = std::numeric_limits<Value>::max();
deba@2337:       for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
deba@2337:         Value value = 0;
deba@2337:         for (typename AuxGraph::IncEdgeIt e(*_aux_graph, n); 
deba@2337:              e != INVALID; ++e) {
deba@2337:           value += (*_aux_capacity)[e];
deba@2337:         }
deba@2337:         if (_min_cut > value) {
deba@2337:           _min_cut = value;
deba@2337:           _cut[0] = (*_first)[n];
deba@2337:         } 
deba@2337:         (*_aux_cut_value)[n] = value;
deba@2337:       }
deba@2337:     }
deba@2337:     
deba@2337: 
deba@2284:   public :
deba@2284: 
deba@2284:     typedef NagamochiIbaraki Create;
deba@2284: 
deba@2284: 
deba@2284:     /// \brief Constructor.
deba@2284:     ///
deba@2284:     ///\param graph the graph the algorithm will run on.
deba@2284:     ///\param capacity the capacity map used by the algorithm.
deba@2284:     NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity) 
deba@2284:       : _graph(&graph), 
deba@2284:         _capacity(&capacity), local_capacity(false),
deba@2284:         _aux_graph(0), local_aux_graph(false),
deba@2284:         _aux_capacity(0), local_aux_capacity(false),
deba@2337:         _aux_cut_value(0), local_aux_cut_value(false),
deba@2284:         _heap_cross_ref(0), local_heap_cross_ref(false),
deba@2284:         _heap(0), local_heap(false),
deba@2284:         _first(0), _last(0), _next(0) {}
deba@2284: 
deba@2284:     /// \brief Constructor.
deba@2284:     ///
deba@2284:     /// This constructor can be used only when the Traits class
deba@2284:     /// defines how can we instantiate a local capacity map.
deba@2530:     /// If the DefUnitCapacity used the algorithm automatically
deba@2284:     /// construct the capacity map.
deba@2284:     ///
deba@2284:     ///\param graph the graph the algorithm will run on.
deba@2284:     NagamochiIbaraki(const Graph& graph) 
deba@2284:       : _graph(&graph), 
deba@2284:         _capacity(0), local_capacity(false),
deba@2284:         _aux_graph(0), local_aux_graph(false),
deba@2284:         _aux_capacity(0), local_aux_capacity(false),
deba@2337:         _aux_cut_value(0), local_aux_cut_value(false),
deba@2284:         _heap_cross_ref(0), local_heap_cross_ref(false),
deba@2284:         _heap(0), local_heap(false),
deba@2284:         _first(0), _last(0), _next(0) {}
deba@2284: 
deba@2284:     /// \brief Destructor.
deba@2284:     ///
deba@2284:     /// Destructor.
deba@2284:     ~NagamochiIbaraki() {
deba@2284:       if (local_heap) delete _heap;
deba@2284:       if (local_heap_cross_ref) delete _heap_cross_ref;
deba@2284:       if (_first) delete _first;
deba@2284:       if (_last) delete _last;
deba@2284:       if (_next) delete _next;
deba@2284:       if (local_aux_capacity) delete _aux_capacity;
deba@2337:       if (local_aux_cut_value) delete _aux_cut_value;
deba@2284:       if (local_aux_graph) delete _aux_graph;
deba@2284:       if (local_capacity) delete _capacity;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the heap and the cross reference used by algorithm.
deba@2284:     ///
deba@2284:     /// Sets the heap and the cross reference used by algorithm.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated heap and cross reference, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2386:     NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
deba@2284:     {
deba@2284:       if (local_heap_cross_ref) {
deba@2284: 	delete _heap_cross_ref;
deba@2284: 	local_heap_cross_ref=false;
deba@2284:       }
deba@2386:       _heap_cross_ref = &cr;
deba@2284:       if (local_heap) {
deba@2284: 	delete _heap;
deba@2284: 	local_heap=false;
deba@2284:       }
deba@2386:       _heap = &hp;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the aux graph.
deba@2284:     ///
deba@2284:     /// Sets the aux graph used by algorithm.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated graph, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2284:     NagamochiIbaraki &auxGraph(AuxGraph& aux_graph)
deba@2284:     {
deba@2284:       if(local_aux_graph) {
deba@2284: 	delete _aux_graph;
deba@2284: 	local_aux_graph=false;
deba@2284:       }
deba@2284:       _aux_graph = &aux_graph;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Sets the aux capacity map.
deba@2284:     ///
deba@2284:     /// Sets the aux capacity map used by algorithm.
deba@2284:     /// If you don't use this function before calling \ref run(),
deba@2284:     /// it will allocate one. The destuctor deallocates this
deba@2284:     /// automatically allocated graph, of course.
deba@2284:     /// \return <tt> (*this) </tt>
deba@2284:     NagamochiIbaraki &auxCapacityMap(AuxCapacityMap& aux_capacity_map)
deba@2284:     {
deba@2284:       if(local_aux_capacity) {
deba@2284: 	delete _aux_capacity;
deba@2284: 	local_aux_capacity=false;
deba@2284:       }
deba@2284:       _aux_capacity = &aux_capacity_map;
deba@2284:       return *this;
deba@2284:     }
deba@2284: 
deba@2284:     /// \name Execution control
deba@2284:     /// The simplest way to execute the algorithm is to use
deba@2284:     /// one of the member functions called \c run().
deba@2284:     /// \n
deba@2284:     /// If you need more control on the execution,
deba@2284:     /// first you must call \ref init() and then call the start()
deba@2284:     /// or proper times the processNextPhase() member functions.
deba@2284: 
deba@2284:     ///@{
deba@2284: 
deba@2284:     /// \brief Initializes the internal data structures.
deba@2284:     ///
deba@2284:     /// Initializes the internal data structures.
deba@2284:     void init() {
deba@2284:       _node_num = countNodes(*_graph);
deba@2337:       createStructures();
deba@2337:       createAuxGraph();
deba@2284:     }
deba@2284: 
deba@2337:   private:
deba@2337: 
deba@2337:     struct EdgeInfo {
deba@2337:       typename AuxGraph::Node source, target;
deba@2337:       Value capacity;
deba@2337:     };
deba@2337:     
deba@2337:     struct EdgeInfoLess {
deba@2337:       bool operator()(const EdgeInfo& left, const EdgeInfo& right) const {
deba@2337:         return (left.source < right.source) || 
deba@2337:           (left.source == right.source && left.target < right.target);
deba@2337:       }
deba@2337:     };
deba@2337: 
deba@2337:   public:
deba@2337: 
deba@2337: 
deba@2284:     /// \brief Processes the next phase
deba@2284:     ///
deba@2337:     /// Processes the next phase in the algorithm. The function should
deba@2337:     /// be called at most countNodes(graph) - 1 times to get surely
deba@2337:     /// the min cut in the graph.
deba@2284:     ///
deba@2284:     ///\return %True when the algorithm finished.
deba@2284:     bool processNextPhase() {
deba@2284:       if (_node_num <= 1) return true;
deba@2284: 
deba@2284:       typedef typename AuxGraph::Node Node;
deba@2284:       typedef typename AuxGraph::NodeIt NodeIt;
deba@2284:       typedef typename AuxGraph::UEdge UEdge;
deba@2337:       typedef typename AuxGraph::UEdgeIt UEdgeIt;
deba@2284:       typedef typename AuxGraph::IncEdgeIt IncEdgeIt;
deba@2284:       
deba@2337:       typename AuxGraph::template UEdgeMap<Value> _edge_cut(*_aux_graph);
deba@2337: 
deba@2337: 
deba@2337:       for (NodeIt n(*_aux_graph); n != INVALID; ++n) {
deba@2337:         _heap_cross_ref->set(n, Heap::PRE_HEAP);
deba@2284:       }
deba@2284: 
deba@2337:       std::vector<Node> nodes;
deba@2337:       nodes.reserve(_node_num);
deba@2337:       int sep = 0;
deba@2284: 
deba@2337:       Value alpha = 0;
deba@2337:       Value emc = std::numeric_limits<Value>::max();
deba@2284: 
deba@2337:       _heap->push(typename AuxGraph::NodeIt(*_aux_graph), 0);
deba@2337:       while (!_heap->empty()) {
deba@2337:         Node node = _heap->top();
deba@2337:         Value value = _heap->prio();
deba@2337:         
deba@2337:         _heap->pop();
deba@2337:         for (typename AuxGraph::IncEdgeIt e(*_aux_graph, node); 
deba@2337:              e != INVALID; ++e) {
deba@2337:           Node tn = _aux_graph->runningNode(e);
deba@2337:           switch (_heap->state(tn)) {
deba@2337:           case Heap::PRE_HEAP:
deba@2337:             _heap->push(tn, (*_aux_capacity)[e]);
deba@2337:             _edge_cut[e] = (*_heap)[tn];
deba@2337:             break;
deba@2337:           case Heap::IN_HEAP:
deba@2337:             _heap->decrease(tn, (*_aux_capacity)[e] + (*_heap)[tn]);
deba@2337:             _edge_cut[e] = (*_heap)[tn];
deba@2337:             break;
deba@2337:           case Heap::POST_HEAP:
deba@2337:             break;
deba@2337:           }
deba@2337:         }
deba@2284: 
deba@2337:         alpha += (*_aux_cut_value)[node];
deba@2337:         alpha -= 2 * value;
deba@2284: 
deba@2337:         nodes.push_back(node);
deba@2337:         if (!_heap->empty()) {
deba@2337:           if (alpha < emc) {
deba@2337:             emc = alpha;
deba@2337:             sep = nodes.size();
deba@2337:           }
deba@2284:         }
deba@2284:       }
deba@2284: 
deba@2386:       if (int(nodes.size()) < _node_num) {
deba@2337:         _cut.clear();
deba@2386:         for (int i = 0; i < int(nodes.size()); ++i) {
deba@2337:           typename Graph::Node n = (*_first)[nodes[i]];
deba@2337:           while (n != INVALID) {
deba@2337:             _cut.push_back(n);
deba@2337:             n = (*_next)[n];
deba@2337:           }
deba@2337:         }
deba@2595: 	_aux_graph->clear();
deba@2595:         _node_num = 1;
deba@2337:         _min_cut = 0;
deba@2337:         return true;
deba@2284:       }
deba@2284: 
deba@2337:       if (emc < _min_cut) {
deba@2337:         _cut.clear();
deba@2337:         for (int i = 0; i < sep; ++i) {
deba@2337:           typename Graph::Node n = (*_first)[nodes[i]];
deba@2337:           while (n != INVALID) {
deba@2337:             _cut.push_back(n);
deba@2337:             n = (*_next)[n];
deba@2337:           }
deba@2337:         }
deba@2337:         _min_cut = emc;
deba@2337:       }
deba@2284: 
deba@2337:       typedef typename AuxGraph::template NodeMap<int> UfeCr;
deba@2337:       UfeCr ufecr(*_aux_graph);
deba@2337:       typedef UnionFindEnum<UfeCr> Ufe; 
deba@2337:       Ufe ufe(ufecr);
deba@2337: 
deba@2337:       for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
deba@2337:         ufe.insert(n);
deba@2337:       }
deba@2337: 
deba@2337:       for (typename AuxGraph::UEdgeIt e(*_aux_graph); e != INVALID; ++e) {
deba@2337:         if (_edge_cut[e] >= emc) {
deba@2337:           ufe.join(_aux_graph->source(e), _aux_graph->target(e));
deba@2284:         }
deba@2284:       }
deba@2284: 
deba@2386:       typedef typename Ufe::ClassIt UfeCIt;
deba@2386:       if (ufe.size(UfeCIt(ufe)) == _node_num) {
deba@2337:         _aux_graph->clear();
deba@2337:         _node_num = 1;
deba@2337:         return true;
deba@2337:       }
deba@2337:       
deba@2337:       std::vector<typename AuxGraph::Node> remnodes;
deba@2337: 
deba@2337:       typename AuxGraph::template NodeMap<UEdge> edges(*_aux_graph, INVALID);
deba@2337:       for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
deba@2337:         if (ufe.size(c) == 1) continue;
deba@2506: 	Node cn = ufe.item(c);
deba@2337:         for (typename Ufe::ItemIt r(ufe, c); r != INVALID; ++r) {
deba@2506:           if (static_cast<Node>(r) == static_cast<Node>(cn)) continue;
deba@2506:           _next->set((*_last)[cn], (*_first)[r]);
deba@2506:           _last->set(cn, (*_last)[r]);
deba@2337:           remnodes.push_back(r);
deba@2337:           --_node_num;
deba@2337:         }
deba@2337:       }
deba@2337: 
deba@2337:       std::vector<EdgeInfo> addedges;
deba@2337:       std::vector<UEdge> remedges;
deba@2337: 
deba@2337:       for (typename AuxGraph::UEdgeIt e(*_aux_graph);
deba@2337:            e != INVALID; ++e) {
deba@2506: 	int sc = ufe.find(_aux_graph->source(e));
deba@2506: 	int tc = ufe.find(_aux_graph->target(e));
deba@2506:         if ((ufe.size(sc) == 1 && ufe.size(tc) == 1)) {
deba@2337:           continue;
deba@2337:         }
deba@2506:         if (sc == tc) {
deba@2337:           remedges.push_back(e);
deba@2337:           continue;
deba@2337:         }
deba@2506:         Node sn = ufe.item(sc);
deba@2506:         Node tn = ufe.item(tc);
deba@2506: 
deba@2337:         EdgeInfo info;
deba@2337:         if (sn < tn) {
deba@2337:           info.source = sn;
deba@2337:           info.target = tn;
deba@2337:         } else {
deba@2337:           info.source = tn;
deba@2337:           info.target = sn;
deba@2337:         }
deba@2337:         info.capacity = (*_aux_capacity)[e];
deba@2337:         addedges.push_back(info);
deba@2337:         remedges.push_back(e);
deba@2337:       }
deba@2337: 
deba@2386:       for (int i = 0; i < int(remedges.size()); ++i) {
deba@2337:         _aux_graph->erase(remedges[i]);
deba@2337:       }
deba@2337: 
deba@2337:       sort(addedges.begin(), addedges.end(), EdgeInfoLess());
deba@2337: 
deba@2337:       {
deba@2337:         int i = 0;
deba@2386:         while (i < int(addedges.size())) {
deba@2337:           Node sn = addedges[i].source;
deba@2337:           Node tn = addedges[i].target;
deba@2337:           Value ec = addedges[i].capacity;
deba@2337:           ++i;
deba@2386:           while (i < int(addedges.size()) && 
deba@2337:                  sn == addedges[i].source && tn == addedges[i].target) {
deba@2337:             ec += addedges[i].capacity;
deba@2337:             ++i;
deba@2337:           }
deba@2337:           typename AuxGraph::UEdge ne = _aux_graph->addEdge(sn, tn);
deba@2337:           (*_aux_capacity)[ne] = ec;
deba@2337:         }
deba@2337:       }
deba@2337: 
deba@2337:       for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
deba@2337:         if (ufe.size(c) == 1) continue;
deba@2506: 	Node cn = ufe.item(c);
deba@2337:         Value cutvalue = 0;
deba@2506:         for (typename AuxGraph::IncEdgeIt e(*_aux_graph, cn);
deba@2337:              e != INVALID; ++e) {
deba@2337:           cutvalue += (*_aux_capacity)[e];
deba@2337:         }
deba@2337:         
deba@2506:         (*_aux_cut_value)[cn] = cutvalue;
deba@2337:         
deba@2337:       }
deba@2337: 
deba@2386:       for (int i = 0; i < int(remnodes.size()); ++i) {
deba@2337:         _aux_graph->erase(remnodes[i]);
deba@2337:       }
deba@2337: 
deba@2284:       return _node_num == 1;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Executes the algorithm.
deba@2284:     ///
deba@2284:     /// Executes the algorithm.
deba@2284:     ///
deba@2284:     /// \pre init() must be called
deba@2284:     void start() {
deba@2284:       while (!processNextPhase());
deba@2284:     }
deba@2284: 
deba@2284: 
deba@2284:     /// \brief Runs %NagamochiIbaraki algorithm.
deba@2284:     ///
deba@2284:     /// This method runs the %Min cut algorithm
deba@2284:     ///
deba@2284:     /// \note mc.run(s) is just a shortcut of the following code.
deba@2284:     ///\code
deba@2284:     ///  mc.init();
deba@2284:     ///  mc.start();
deba@2284:     ///\endcode
deba@2284:     void run() {
deba@2284:       init();
deba@2284:       start();
deba@2284:     }
deba@2284: 
deba@2284:     ///@}
deba@2284: 
deba@2284:     /// \name Query Functions 
deba@2284:     ///
deba@2284:     /// The result of the %NagamochiIbaraki
deba@2284:     /// algorithm can be obtained using these functions.\n 
deba@2284:     /// Before the use of these functions, either run() or start()
deba@2284:     /// must be called.
deba@2284:     
deba@2284:     ///@{
deba@2284: 
deba@2284:     /// \brief Returns the min cut value.
deba@2284:     ///
deba@2284:     /// Returns the min cut value if the algorithm finished.
deba@2284:     /// After the first processNextPhase() it is a value of a
deba@2284:     /// valid cut in the graph.
deba@2284:     Value minCut() const {
deba@2284:       return _min_cut;
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Returns a min cut in a NodeMap.
deba@2284:     ///
deba@2284:     /// It sets the nodes of one of the two partitions to true in
deba@2284:     /// the given BoolNodeMap. The map contains a valid cut if the
deba@2284:     /// map have been set false previously. 
deba@2284:     template <typename NodeMap>
deba@2284:     Value quickMinCut(NodeMap& nodeMap) const { 
deba@2386:       for (int i = 0; i < int(_cut.size()); ++i) {
deba@2337:         nodeMap.set(_cut[i], true);
deba@2337:       }
deba@2284:       return minCut();
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Returns a min cut in a NodeMap.
deba@2284:     ///
deba@2284:     /// It sets the nodes of one of the two partitions to true and
deba@2284:     /// the other partition to false. The function first set all of the
deba@2284:     /// nodes to false and after it call the quickMinCut() member.
deba@2284:     template <typename NodeMap>
deba@2284:     Value minCut(NodeMap& nodeMap) const { 
deba@2284:       for (typename Graph::NodeIt it(*_graph); it != INVALID; ++it) {
deba@2284:         nodeMap.set(it, false);      
deba@2284:       }
deba@2284:       quickMinCut(nodeMap);
deba@2284:       return minCut();
deba@2284:     }
deba@2284: 
deba@2284:     /// \brief Returns a min cut in an EdgeMap.
deba@2284:     ///
deba@2284:     /// If an undirected edge is in a min cut then it will be
deba@2284:     /// set to true and the others will be set to false in the given map.
deba@2284:     template <typename EdgeMap>
deba@2284:     Value cutEdges(EdgeMap& edgeMap) const {
deba@2284:       typename Graph::template NodeMap<bool> cut(*_graph, false);
deba@2284:       quickMinCut(cut);
deba@2284:       for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
deba@2284:         edgeMap.set(it, cut[_graph->source(it)] ^ cut[_graph->target(it)]);
deba@2284:       }
deba@2284:       return minCut();
deba@2284:     }
deba@2284: 
deba@2284:     ///@}
deba@2284: 
deba@2337:   private:
deba@2337: 
deba@2337: 
deba@2284:   };
deba@2284: }
deba@2284: 
deba@2284: #endif