Reimplementation of Hao-Orlin algorithm
authordeba
Tue, 04 Dec 2007 10:55:27 +0000
changeset 2530f86f7e4eb2ba
parent 2529 93de38566e6c
child 2531 426a4e35e167
Reimplementation of Hao-Orlin algorithm
Little modifictaion in NagamochiIbaraki
More docs for minimum cut algorithms
doc/groups.dox
lemon/hao_orlin.h
lemon/nagamochi_ibaraki.h
     1.1 --- a/doc/groups.dox	Fri Nov 30 09:22:38 2007 +0000
     1.2 +++ b/doc/groups.dox	Tue Dec 04 10:55:27 2007 +0000
     1.3 @@ -258,13 +258,34 @@
     1.4  */
     1.5  
     1.6  /**
     1.7 -@defgroup min_cut Minimum Cut algorithms
     1.8 -@ingroup algs
     1.9 -\brief This group describes the algorithms
    1.10 -for finding minimum cut in graphs.
    1.11 +@defgroup min_cut Minimum Cut algorithms 
    1.12 +@ingroup algs 
    1.13  
    1.14 -This group describes the algorithms
    1.15 -for finding minimum cut in graphs.
    1.16 +\brief This group describes the algorithms for finding minimum cut in
    1.17 +graphs.
    1.18 +
    1.19 +This group describes the algorithms for finding minimum cut in graphs.
    1.20 +
    1.21 +The minimum cut problem is to find a non-empty and non-complete
    1.22 +\f$X\f$ subset of the vertices with minimum overall capacity on
    1.23 +outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
    1.24 +\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
    1.25 +cut is the solution of the next optimization problem:
    1.26 +
    1.27 +\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
    1.28 +
    1.29 +The lemon contains several algorithms related to minimum cut problems:
    1.30 +
    1.31 +- \ref lemon::HaoOrlin "Hao-Orlin algorithm" for calculate minimum cut
    1.32 +  in directed graphs  
    1.33 +- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
    1.34 +  calculate minimum cut in undirected graphs
    1.35 +- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" for calculate all
    1.36 +  pairs minimum cut in undirected graphs
    1.37 +
    1.38 +If you want to find minimum cut just between two distinict nodes,
    1.39 +please see the \ref max_flow "Maximum Flow page".
    1.40 +
    1.41  */
    1.42  
    1.43  /**
     2.1 --- a/lemon/hao_orlin.h	Fri Nov 30 09:22:38 2007 +0000
     2.2 +++ b/lemon/hao_orlin.h	Tue Dec 04 10:55:27 2007 +0000
     2.3 @@ -19,13 +19,9 @@
     2.4  #ifndef LEMON_HAO_ORLIN_H
     2.5  #define LEMON_HAO_ORLIN_H
     2.6  
     2.7 -#include <cassert>
     2.8 - 
     2.9 -
    2.10 -
    2.11  #include <vector>
    2.12 -#include <queue>
    2.13  #include <list>
    2.14 +#include <ext/hash_set>
    2.15  #include <limits>
    2.16  
    2.17  #include <lemon/maps.h>
    2.18 @@ -37,7 +33,7 @@
    2.19  /// \ingroup min_cut
    2.20  /// \brief Implementation of the Hao-Orlin algorithm.
    2.21  ///
    2.22 -/// Implementation of the HaoOrlin algorithms class for testing network 
    2.23 +/// Implementation of the Hao-Orlin algorithm class for testing network 
    2.24  /// reliability.
    2.25  
    2.26  namespace lemon {
    2.27 @@ -46,24 +42,25 @@
    2.28    ///
    2.29    /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
    2.30    ///
    2.31 -  /// Hao-Orlin calculates a minimum cut in a directed graph 
    2.32 -  /// \f$ D=(V,A) \f$. It takes a fixed node \f$ source \in V \f$ and consists
    2.33 -  /// of two phases: in the first phase it determines a minimum cut
    2.34 -  /// with \f$ source \f$ on the source-side (i.e. a set \f$ X\subsetneq V \f$
    2.35 -  /// with \f$ source \in X \f$ and minimal out-degree) and in the
    2.36 -  /// second phase it determines a minimum cut with \f$ source \f$ on the
    2.37 -  /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \notin X \f$
    2.38 -  /// and minimal out-degree). Obviously, the smaller of these two
    2.39 -  /// cuts will be a minimum cut of \f$ D \f$. The algorithm is a
    2.40 -  /// modified push-relabel preflow algorithm and our implementation
    2.41 -  /// calculates the minimum cut in \f$ O(n^3) \f$ time (we use the
    2.42 -  /// highest-label rule). The purpose of such an algorithm is testing
    2.43 -  /// network reliability. For an undirected graph with \f$ n \f$
    2.44 -  /// nodes and \f$ e \f$ edges you can use the algorithm of Nagamochi
    2.45 -  /// and Ibaraki which solves the undirected problem in 
    2.46 -  /// \f$ O(ne + n^2 \log(n)) \f$ time: it is implemented in the MinCut 
    2.47 -  /// algorithm
    2.48 -  /// class.
    2.49 +  /// Hao-Orlin calculates a minimum cut in a directed graph
    2.50 +  /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
    2.51 +  /// consists of two phases: in the first phase it determines a
    2.52 +  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
    2.53 +  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
    2.54 +  /// out-degree) and in the second phase it determines a minimum cut
    2.55 +  /// with \f$ source \f$ on the sink-side (i.e. a set 
    2.56 +  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
    2.57 +  /// out-degree). Obviously, the smaller of these two cuts will be a
    2.58 +  /// minimum cut of \f$ D \f$. The algorithm is a modified
    2.59 +  /// push-relabel preflow algorithm and our implementation calculates
    2.60 +  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
    2.61 +  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
    2.62 +  /// purpose of such algorithm is testing network reliability. For an
    2.63 +  /// undirected graph you can run just the first phase of the
    2.64 +  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
    2.65 +  /// which solves the undirected problem in 
    2.66 +  /// \f$ O(nm + n^2 \log(n)) \f$ time: it is implemented in the
    2.67 +  /// NagamochiIbaraki algorithm class.
    2.68    ///
    2.69    /// \param _Graph is the graph type of the algorithm.
    2.70    /// \param _CapacityMap is an edge map of capacities which should
    2.71 @@ -80,7 +77,7 @@
    2.72              typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
    2.73  #endif
    2.74    class HaoOrlin {
    2.75 -  protected:
    2.76 +  private:
    2.77  
    2.78      typedef _Graph Graph;
    2.79      typedef _CapacityMap CapacityMap;
    2.80 @@ -88,44 +85,29 @@
    2.81  
    2.82      typedef typename CapacityMap::Value Value;
    2.83  
    2.84 +    GRAPH_TYPEDEFS(typename Graph);
    2.85      
    2.86 -    typedef typename Graph::Node Node;
    2.87 -    typedef typename Graph::NodeIt NodeIt;
    2.88 -    typedef typename Graph::EdgeIt EdgeIt;
    2.89 -    typedef typename Graph::OutEdgeIt OutEdgeIt;
    2.90 -    typedef typename Graph::InEdgeIt InEdgeIt;
    2.91 -
    2.92 -    const Graph* _graph;
    2.93 -
    2.94 +    const Graph& _graph;
    2.95      const CapacityMap* _capacity;
    2.96  
    2.97      typedef typename Graph::template EdgeMap<Value> FlowMap;
    2.98 +    FlowMap* _flow;
    2.99  
   2.100 -    FlowMap* _preflow;
   2.101 +    Node _source;
   2.102  
   2.103 -    Node _source, _target;
   2.104      int _node_num;
   2.105  
   2.106 -    typedef ResGraphAdaptor<const Graph, Value, CapacityMap, 
   2.107 -                            FlowMap, Tolerance> OutResGraph;
   2.108 -    typedef typename OutResGraph::Edge OutResEdge;
   2.109 +    // Bucketing structure
   2.110 +    std::vector<Node> _first, _last;
   2.111 +    typename Graph::template NodeMap<Node>* _next;
   2.112 +    typename Graph::template NodeMap<Node>* _prev;    
   2.113 +    typename Graph::template NodeMap<bool>* _active;
   2.114 +    typename Graph::template NodeMap<int>* _bucket;
   2.115      
   2.116 -    OutResGraph* _out_res_graph;
   2.117 +    std::vector<bool> _dormant;
   2.118  
   2.119 -    typedef RevGraphAdaptor<const Graph> RevGraph;
   2.120 -    RevGraph* _rev_graph;
   2.121 -
   2.122 -    typedef ResGraphAdaptor<const RevGraph, Value, CapacityMap, 
   2.123 -                            FlowMap, Tolerance> InResGraph;
   2.124 -    typedef typename InResGraph::Edge InResEdge;
   2.125 -    
   2.126 -    InResGraph* _in_res_graph;
   2.127 -
   2.128 -    typedef IterableBoolMap<Graph, Node> WakeMap;
   2.129 -    WakeMap* _wake;
   2.130 -
   2.131 -    typedef typename Graph::template NodeMap<int> DistMap;
   2.132 -    DistMap* _dist;  
   2.133 +    std::list<std::list<int> > _sets;
   2.134 +    std::list<int>::iterator _highest;
   2.135      
   2.136      typedef typename Graph::template NodeMap<Value> ExcessMap;
   2.137      ExcessMap* _excess;
   2.138 @@ -133,15 +115,6 @@
   2.139      typedef typename Graph::template NodeMap<bool> SourceSetMap;
   2.140      SourceSetMap* _source_set;
   2.141  
   2.142 -    std::vector<int> _level_size;
   2.143 -
   2.144 -    int _highest_active;
   2.145 -    std::vector<std::list<Node> > _active_nodes;
   2.146 -
   2.147 -    int _dormant_max;
   2.148 -    std::vector<std::list<Node> > _dormant;
   2.149 -
   2.150 -
   2.151      Value _min_cut;
   2.152  
   2.153      typedef typename Graph::template NodeMap<bool> MinCutMap;
   2.154 @@ -156,267 +129,695 @@
   2.155      /// Constructor of the algorithm class. 
   2.156      HaoOrlin(const Graph& graph, const CapacityMap& capacity, 
   2.157               const Tolerance& tolerance = Tolerance()) :
   2.158 -      _graph(&graph), _capacity(&capacity), 
   2.159 -      _preflow(0), _source(), _target(), 
   2.160 -      _out_res_graph(0), _rev_graph(0), _in_res_graph(0),
   2.161 -      _wake(0),_dist(0), _excess(0), _source_set(0), 
   2.162 -      _highest_active(), _active_nodes(), _dormant_max(), _dormant(), 
   2.163 -      _min_cut(), _min_cut_map(0), _tolerance(tolerance) {}
   2.164 +      _graph(graph), _capacity(&capacity), _flow(0), _source(),
   2.165 +      _node_num(), _first(), _last(), _next(0), _prev(0), 
   2.166 +      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
   2.167 +      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0), 
   2.168 +      _tolerance(tolerance) {}
   2.169  
   2.170      ~HaoOrlin() {
   2.171        if (_min_cut_map) {
   2.172          delete _min_cut_map;
   2.173        } 
   2.174 -      if (_in_res_graph) {
   2.175 -        delete _in_res_graph;
   2.176 -      }
   2.177 -      if (_rev_graph) {
   2.178 -        delete _rev_graph;
   2.179 -      }
   2.180 -      if (_out_res_graph) {
   2.181 -        delete _out_res_graph;
   2.182 -      }
   2.183        if (_source_set) {
   2.184          delete _source_set;
   2.185        }
   2.186        if (_excess) {
   2.187          delete _excess;
   2.188        }
   2.189 -      if (_dist) {
   2.190 -        delete _dist;
   2.191 +      if (_next) {
   2.192 +	delete _next;
   2.193        }
   2.194 -      if (_wake) {
   2.195 -        delete _wake;
   2.196 +      if (_prev) {
   2.197 +	delete _prev;
   2.198        }
   2.199 -      if (_preflow) {
   2.200 -        delete _preflow;
   2.201 +      if (_active) {
   2.202 +	delete _active;
   2.203 +      }
   2.204 +      if (_bucket) {
   2.205 +	delete _bucket;
   2.206 +      }
   2.207 +      if (_flow) {
   2.208 +        delete _flow;
   2.209        }
   2.210      }
   2.211      
   2.212    private:
   2.213 +
   2.214 +    void activate(const Node& i) {
   2.215 +      _active->set(i, true);
   2.216 +
   2.217 +      int bucket = (*_bucket)[i];
   2.218 +
   2.219 +      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;	    
   2.220 +      //unlace
   2.221 +      _next->set((*_prev)[i], (*_next)[i]);
   2.222 +      if ((*_next)[i] != INVALID) {
   2.223 +	_prev->set((*_next)[i], (*_prev)[i]);
   2.224 +      } else {
   2.225 +	_last[bucket] = (*_prev)[i];
   2.226 +      }
   2.227 +      //lace
   2.228 +      _next->set(i, _first[bucket]);
   2.229 +      _prev->set(_first[bucket], i);
   2.230 +      _prev->set(i, INVALID);
   2.231 +      _first[bucket] = i;
   2.232 +    }
   2.233 +
   2.234 +    void deactivate(const Node& i) {
   2.235 +      _active->set(i, false);
   2.236 +      int bucket = (*_bucket)[i];
   2.237 +
   2.238 +      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
   2.239 +      
   2.240 +      //unlace
   2.241 +      _prev->set((*_next)[i], (*_prev)[i]);
   2.242 +      if ((*_prev)[i] != INVALID) {
   2.243 +	_next->set((*_prev)[i], (*_next)[i]);
   2.244 +      } else {
   2.245 +	_first[bucket] = (*_next)[i];
   2.246 +      }
   2.247 +      //lace
   2.248 +      _prev->set(i, _last[bucket]);
   2.249 +      _next->set(_last[bucket], i);
   2.250 +      _next->set(i, INVALID);
   2.251 +      _last[bucket] = i;
   2.252 +    }
   2.253 +
   2.254 +    void addItem(const Node& i, int bucket) {
   2.255 +      (*_bucket)[i] = bucket;
   2.256 +      if (_last[bucket] != INVALID) {
   2.257 +	_prev->set(i, _last[bucket]);
   2.258 +	_next->set(_last[bucket], i);
   2.259 +	_next->set(i, INVALID);
   2.260 +	_last[bucket] = i;
   2.261 +      } else {
   2.262 +	_prev->set(i, INVALID);
   2.263 +	_first[bucket] = i;
   2.264 +	_next->set(i, INVALID);
   2.265 +	_last[bucket] = i;
   2.266 +      }
   2.267 +    }
   2.268      
   2.269 -    template <typename ResGraph>
   2.270 -    void findMinCut(const Node& target, bool out, ResGraph& res_graph) {
   2.271 -      typedef typename ResGraph::Edge ResEdge;
   2.272 -      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
   2.273 +    void findMinCutOut() {
   2.274  
   2.275 -      for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
   2.276 -        (*_preflow)[it] = 0;      
   2.277 -      }
   2.278 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
   2.279 -        (*_wake)[it] = true;
   2.280 -        (*_dist)[it] = 1;
   2.281 -        (*_excess)[it] = 0;
   2.282 -        (*_source_set)[it] = false;
   2.283 +      for (NodeIt n(_graph); n != INVALID; ++n) {
   2.284 +	_excess->set(n, 0);
   2.285        }
   2.286  
   2.287 -      _dormant[0].push_front(_source);
   2.288 -      (*_source_set)[_source] = true;
   2.289 -      _dormant_max = 0;
   2.290 -      (*_wake)[_source] = false;
   2.291 -
   2.292 -      _level_size[0] = 1;
   2.293 -      _level_size[1] = _node_num - 1;
   2.294 -
   2.295 -      _target = target;
   2.296 -      (*_dist)[target] = 0;
   2.297 -
   2.298 -      for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) {
   2.299 -        Value delta = res_graph.rescap(it);
   2.300 -        (*_excess)[_source] -= delta;
   2.301 -        res_graph.augment(it, delta);
   2.302 -        Node a = res_graph.target(it);
   2.303 -        if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
   2.304 -          _active_nodes[(*_dist)[a]].push_front(a);
   2.305 -          if (_highest_active < (*_dist)[a]) {
   2.306 -            _highest_active = (*_dist)[a];
   2.307 -          }
   2.308 -        }
   2.309 -        (*_excess)[a] += delta;
   2.310 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
   2.311 +	_flow->set(e, 0);
   2.312        }
   2.313  
   2.314 +      int bucket_num = 1;
   2.315 +      
   2.316 +      {
   2.317 +	typename Graph::template NodeMap<bool> reached(_graph, false);
   2.318 +	
   2.319 +	reached.set(_source, true);
   2.320  
   2.321 -      do {
   2.322 -	Node n;
   2.323 -	while ((n = findActiveNode()) != INVALID) {
   2.324 -	  for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
   2.325 -            Node a = res_graph.target(e);
   2.326 -            if ((*_dist)[a] >= (*_dist)[n] || !(*_wake)[a]) continue;
   2.327 -	    Value delta = res_graph.rescap(e);
   2.328 -	    if (_tolerance.positive((*_excess)[n] - delta)) {
   2.329 -              (*_excess)[n] -= delta;
   2.330 -	    } else {
   2.331 -	      delta = (*_excess)[n];
   2.332 -              (*_excess)[n] = 0;
   2.333 +	bool first_set = true;
   2.334 +
   2.335 +	for (NodeIt t(_graph); t != INVALID; ++t) {
   2.336 +	  if (reached[t]) continue;
   2.337 +	  _sets.push_front(std::list<int>());
   2.338 +	  _sets.front().push_front(bucket_num);
   2.339 +	  _dormant[bucket_num] = !first_set;
   2.340 +
   2.341 +	  _bucket->set(t, bucket_num);
   2.342 +	  _first[bucket_num] = _last[bucket_num] = t;
   2.343 +	  _next->set(t, INVALID);
   2.344 +	  _prev->set(t, INVALID);
   2.345 +
   2.346 +	  ++bucket_num;
   2.347 +	  
   2.348 +	  std::vector<Node> queue;
   2.349 +	  queue.push_back(t);
   2.350 +	  reached.set(t, true);
   2.351 +	  
   2.352 +	  while (!queue.empty()) {
   2.353 +	    _sets.front().push_front(bucket_num);
   2.354 +	    _dormant[bucket_num] = !first_set;
   2.355 +	    _first[bucket_num] = _last[bucket_num] = INVALID;
   2.356 +	    
   2.357 +	    std::vector<Node> nqueue;
   2.358 +	    for (int i = 0; i < int(queue.size()); ++i) {
   2.359 +	      Node n = queue[i];
   2.360 +	      for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.361 +		Node u = _graph.source(e);
   2.362 +		if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
   2.363 +		  reached.set(u, true);
   2.364 +		  addItem(u, bucket_num);
   2.365 +		  nqueue.push_back(u);
   2.366 +		}
   2.367 +	      }
   2.368  	    }
   2.369 -	    res_graph.augment(e, delta);
   2.370 -	    if ((*_excess)[a] == 0 && a != _target) {
   2.371 -	      _active_nodes[(*_dist)[a]].push_front(a);
   2.372 -	    }
   2.373 -	    (*_excess)[a] += delta;
   2.374 -            if ((*_excess)[n] == 0) break;
   2.375 +	    queue.swap(nqueue);
   2.376 +	    ++bucket_num;
   2.377  	  }
   2.378 -	  if ((*_excess)[n] != 0) {
   2.379 -	    relabel(n, res_graph);
   2.380 -          }
   2.381 +	  _sets.front().pop_front();
   2.382 +	  --bucket_num;
   2.383 +	  first_set = false;
   2.384  	}
   2.385  
   2.386 -	Value current_value = cutValue(out);
   2.387 - 	if (_min_cut > current_value){
   2.388 -          if (out) {
   2.389 -            for (NodeIt it(*_graph); it != INVALID; ++it) {
   2.390 -              _min_cut_map->set(it, !(*_wake)[it]);
   2.391 -            } 
   2.392 -          } else {
   2.393 -            for (NodeIt it(*_graph); it != INVALID; ++it) {
   2.394 -              _min_cut_map->set(it, (*_wake)[it]);
   2.395 -            } 
   2.396 -          }
   2.397 -
   2.398 -	  _min_cut = current_value;
   2.399 - 	}
   2.400 -
   2.401 -      } while (selectNewSink(res_graph));
   2.402 -    }
   2.403 -
   2.404 -    template <typename ResGraph>
   2.405 -    void relabel(const Node& n, ResGraph& res_graph) {
   2.406 -      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
   2.407 -
   2.408 -      int k = (*_dist)[n];
   2.409 -      if (_level_size[k] == 1) {
   2.410 -	++_dormant_max;
   2.411 -	for (NodeIt it(*_graph); it != INVALID; ++it) {
   2.412 -	  if ((*_wake)[it] && (*_dist)[it] >= k) {
   2.413 -	    (*_wake)[it] = false;
   2.414 -	    _dormant[_dormant_max].push_front(it);
   2.415 -	    --_level_size[(*_dist)[it]];
   2.416 +	_bucket->set(_source, 0);
   2.417 +	_dormant[0] = true;
   2.418 +      }
   2.419 +      _source_set->set(_source, true);	  
   2.420 +	  
   2.421 +      Node target = _last[_sets.back().back()];
   2.422 +      {
   2.423 +	for (OutEdgeIt e(_graph, _source); e != INVALID; ++e) {
   2.424 +	  if (_tolerance.positive((*_capacity)[e])) {
   2.425 +	    Node u = _graph.target(e);
   2.426 +	    _flow->set(e, (*_capacity)[e]);
   2.427 +	    _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
   2.428 +	    if (!(*_active)[u] && u != _source) {
   2.429 +	      activate(u);
   2.430 +	    }
   2.431  	  }
   2.432  	}
   2.433 -        --_highest_active;
   2.434 -      } else {	
   2.435 -        int new_dist = _node_num;
   2.436 -        for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
   2.437 -          Node t = res_graph.target(e);
   2.438 -          if ((*_wake)[t] && new_dist > (*_dist)[t]) {
   2.439 -            new_dist = (*_dist)[t];
   2.440 -          }
   2.441 -        }
   2.442 -        if (new_dist == _node_num) {
   2.443 -	  ++_dormant_max;
   2.444 -	  (*_wake)[n] = false;
   2.445 -	  _dormant[_dormant_max].push_front(n);
   2.446 -	  --_level_size[(*_dist)[n]];
   2.447 -	} else {	    
   2.448 -	  --_level_size[(*_dist)[n]];
   2.449 -	  (*_dist)[n] = new_dist + 1;
   2.450 -	  _highest_active = (*_dist)[n];
   2.451 -	  _active_nodes[_highest_active].push_front(n);
   2.452 -	  ++_level_size[(*_dist)[n]];
   2.453 +	if ((*_active)[target]) {
   2.454 +	  deactivate(target);
   2.455 +	}
   2.456 +	
   2.457 +	_highest = _sets.back().begin();
   2.458 +	while (_highest != _sets.back().end() && 
   2.459 +	       !(*_active)[_first[*_highest]]) {
   2.460 +	  ++_highest;
   2.461 +	}
   2.462 +      }
   2.463 +
   2.464 +
   2.465 +      while (true) {
   2.466 +	while (_highest != _sets.back().end()) {
   2.467 +	  Node n = _first[*_highest];
   2.468 +	  Value excess = (*_excess)[n];
   2.469 +	  int next_bucket = _node_num;
   2.470 +
   2.471 +	  int under_bucket;
   2.472 +	  if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
   2.473 +	    under_bucket = -1;
   2.474 +	  } else {
   2.475 +	    under_bucket = *(++std::list<int>::iterator(_highest));
   2.476 +	  }
   2.477 +
   2.478 +	  for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.479 +	    Node v = _graph.target(e);
   2.480 +	    if (_dormant[(*_bucket)[v]]) continue;
   2.481 +	    Value rem = (*_capacity)[e] - (*_flow)[e];
   2.482 +	    if (!_tolerance.positive(rem)) continue;
   2.483 +	    if ((*_bucket)[v] == under_bucket) {
   2.484 +	      if (!(*_active)[v] && v != target) {
   2.485 +		activate(v);
   2.486 +	      }
   2.487 +	      if (!_tolerance.less(rem, excess)) {
   2.488 +		_flow->set(e, (*_flow)[e] + excess);
   2.489 +		_excess->set(v, (*_excess)[v] + excess);
   2.490 +		excess = 0;
   2.491 +		goto no_more_push;
   2.492 +	      } else {
   2.493 +		excess -= rem;
   2.494 +		_excess->set(v, (*_excess)[v] + rem);
   2.495 +		_flow->set(e, (*_capacity)[e]);
   2.496 +	      }
   2.497 +	    } else if (next_bucket > (*_bucket)[v]) {
   2.498 +	      next_bucket = (*_bucket)[v];
   2.499 +	    }
   2.500 +	  }
   2.501 +
   2.502 +	  for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.503 +	    Node v = _graph.source(e);
   2.504 +	    if (_dormant[(*_bucket)[v]]) continue;
   2.505 +	    Value rem = (*_flow)[e];
   2.506 +	    if (!_tolerance.positive(rem)) continue;
   2.507 +	    if ((*_bucket)[v] == under_bucket) {
   2.508 +	      if (!(*_active)[v] && v != target) {
   2.509 +		activate(v);
   2.510 +	      }
   2.511 +	      if (!_tolerance.less(rem, excess)) {
   2.512 +		_flow->set(e, (*_flow)[e] - excess);
   2.513 +		_excess->set(v, (*_excess)[v] + excess);
   2.514 +		excess = 0;
   2.515 +		goto no_more_push;
   2.516 +	      } else {
   2.517 +		excess -= rem;
   2.518 +		_excess->set(v, (*_excess)[v] + rem);
   2.519 +		_flow->set(e, 0);
   2.520 +	      }
   2.521 +	    } else if (next_bucket > (*_bucket)[v]) {
   2.522 +	      next_bucket = (*_bucket)[v];
   2.523 +	    }
   2.524 +	  }
   2.525 +	  
   2.526 +	no_more_push:
   2.527 +	  
   2.528 +	  _excess->set(n, excess);
   2.529 +	  
   2.530 +	  if (excess != 0) {
   2.531 +	    if ((*_next)[n] == INVALID) {
   2.532 +	      typename std::list<std::list<int> >::iterator new_set = 
   2.533 +		_sets.insert(--_sets.end(), std::list<int>());
   2.534 +	      new_set->splice(new_set->end(), _sets.back(), 
   2.535 +			      _sets.back().begin(), ++_highest);
   2.536 +	      for (std::list<int>::iterator it = new_set->begin();
   2.537 +		   it != new_set->end(); ++it) {
   2.538 +		_dormant[*it] = true;
   2.539 +	      }
   2.540 +	      while (_highest != _sets.back().end() && 
   2.541 +		     !(*_active)[_first[*_highest]]) {
   2.542 +		++_highest;
   2.543 +	      }
   2.544 +	    } else if (next_bucket == _node_num) {
   2.545 +	      _first[(*_bucket)[n]] = (*_next)[n];
   2.546 +	      _prev->set((*_next)[n], INVALID);
   2.547 +	      
   2.548 +	      std::list<std::list<int> >::iterator new_set = 
   2.549 +		_sets.insert(--_sets.end(), std::list<int>());
   2.550 +	      
   2.551 +	      new_set->push_front(bucket_num);
   2.552 +	      _bucket->set(n, bucket_num);
   2.553 +	      _first[bucket_num] = _last[bucket_num] = n;
   2.554 +	      _next->set(n, INVALID);
   2.555 +	      _prev->set(n, INVALID);
   2.556 +	      _dormant[bucket_num] = true;
   2.557 +	      ++bucket_num;
   2.558 +
   2.559 +	      while (_highest != _sets.back().end() && 
   2.560 +		     !(*_active)[_first[*_highest]]) {
   2.561 +		++_highest;
   2.562 +	      }
   2.563 +	    } else {
   2.564 +	      _first[*_highest] = (*_next)[n];
   2.565 +	      _prev->set((*_next)[n], INVALID);
   2.566 +	      
   2.567 +	      while (next_bucket != *_highest) {
   2.568 +		--_highest;
   2.569 +	      }
   2.570 +
   2.571 +	      if (_highest == _sets.back().begin()) {
   2.572 +		_sets.back().push_front(bucket_num);
   2.573 +		_dormant[bucket_num] = false;
   2.574 +		_first[bucket_num] = _last[bucket_num] = INVALID;
   2.575 +		++bucket_num;
   2.576 +	      }
   2.577 +	      --_highest;
   2.578 +
   2.579 +	      _bucket->set(n, *_highest);
   2.580 +	      _next->set(n, _first[*_highest]);
   2.581 +	      if (_first[*_highest] != INVALID) {
   2.582 +		_prev->set(_first[*_highest], n);
   2.583 +	      } else {
   2.584 +		_last[*_highest] = n;
   2.585 +	      }
   2.586 +	      _first[*_highest] = n;	      
   2.587 +	    }
   2.588 +	  } else {
   2.589 +
   2.590 +	    deactivate(n);
   2.591 +	    if (!(*_active)[_first[*_highest]]) {
   2.592 +	      ++_highest;
   2.593 +	      if (_highest != _sets.back().end() && 
   2.594 +		  !(*_active)[_first[*_highest]]) {
   2.595 +		_highest = _sets.back().end();
   2.596 +	      }
   2.597 +	    }
   2.598 +	  }
   2.599 +	}
   2.600 +
   2.601 +	if ((*_excess)[target] < _min_cut) {
   2.602 +	  _min_cut = (*_excess)[target];
   2.603 +	  for (NodeIt i(_graph); i != INVALID; ++i) {
   2.604 +	    _min_cut_map->set(i, true);
   2.605 +	  }
   2.606 +	  for (std::list<int>::iterator it = _sets.back().begin();
   2.607 +	       it != _sets.back().end(); ++it) {
   2.608 +	    Node n = _first[*it];
   2.609 +	    while (n != INVALID) {
   2.610 +	      _min_cut_map->set(n, false);
   2.611 +	      n = (*_next)[n];
   2.612 +	    }
   2.613 +	  }
   2.614 +	}
   2.615 +
   2.616 +	{
   2.617 +	  Node new_target;
   2.618 +	  if ((*_prev)[target] != INVALID) {
   2.619 +	    _last[(*_bucket)[target]] = (*_prev)[target];
   2.620 +	    _next->set((*_prev)[target], INVALID);
   2.621 +	    new_target = (*_prev)[target];
   2.622 +	  } else {
   2.623 +	    _sets.back().pop_back();
   2.624 +	    if (_sets.back().empty()) {
   2.625 +	      _sets.pop_back();
   2.626 +	      if (_sets.empty())
   2.627 +		break;
   2.628 +	      for (std::list<int>::iterator it = _sets.back().begin();
   2.629 +		   it != _sets.back().end(); ++it) {
   2.630 +		_dormant[*it] = false;
   2.631 +	      }
   2.632 +	    }
   2.633 +	    new_target = _last[_sets.back().back()];
   2.634 +	  }
   2.635 +
   2.636 +	  _bucket->set(target, 0);
   2.637 +
   2.638 +	  _source_set->set(target, true);	  
   2.639 +	  for (OutEdgeIt e(_graph, target); e != INVALID; ++e) {
   2.640 +	    Value rem = (*_capacity)[e] - (*_flow)[e];
   2.641 +	    if (!_tolerance.positive(rem)) continue;
   2.642 +	    Node v = _graph.target(e);
   2.643 +	    if (!(*_active)[v] && !(*_source_set)[v]) {
   2.644 +	      activate(v);
   2.645 +	    }
   2.646 +	    _excess->set(v, (*_excess)[v] + rem);
   2.647 +	    _flow->set(e, (*_capacity)[e]);
   2.648 +	  }
   2.649 +	  
   2.650 +	  for (InEdgeIt e(_graph, target); e != INVALID; ++e) {
   2.651 +	    Value rem = (*_flow)[e];
   2.652 +	    if (!_tolerance.positive(rem)) continue;
   2.653 +	    Node v = _graph.source(e);
   2.654 +	    if (!(*_active)[v] && !(*_source_set)[v]) {
   2.655 +	      activate(v);
   2.656 +	    }
   2.657 +	    _excess->set(v, (*_excess)[v] + rem);
   2.658 +	    _flow->set(e, 0);
   2.659 +	  }
   2.660 +	  
   2.661 +	  target = new_target;
   2.662 +	  if ((*_active)[target]) {
   2.663 +	    deactivate(target);
   2.664 +	  }
   2.665 +
   2.666 +	  _highest = _sets.back().begin();
   2.667 +	  while (_highest != _sets.back().end() && 
   2.668 +		 !(*_active)[_first[*_highest]]) {
   2.669 +	    ++_highest;
   2.670 +	  }
   2.671 +	}
   2.672 +      }
   2.673 +    }    
   2.674 +
   2.675 +    void findMinCutIn() {
   2.676 +
   2.677 +      for (NodeIt n(_graph); n != INVALID; ++n) {
   2.678 +	_excess->set(n, 0);
   2.679 +      }
   2.680 +
   2.681 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
   2.682 +	_flow->set(e, 0);
   2.683 +      }
   2.684 +
   2.685 +      int bucket_num = 1;
   2.686 +      
   2.687 +      {
   2.688 +	typename Graph::template NodeMap<bool> reached(_graph, false);
   2.689 +	
   2.690 +	reached.set(_source, true);
   2.691 +
   2.692 +	bool first_set = true;
   2.693 +
   2.694 +	for (NodeIt t(_graph); t != INVALID; ++t) {
   2.695 +	  if (reached[t]) continue;
   2.696 +	  _sets.push_front(std::list<int>());
   2.697 +	  _sets.front().push_front(bucket_num);
   2.698 +	  _dormant[bucket_num] = !first_set;
   2.699 +
   2.700 +	  _bucket->set(t, bucket_num);
   2.701 +	  _first[bucket_num] = _last[bucket_num] = t;
   2.702 +	  _next->set(t, INVALID);
   2.703 +	  _prev->set(t, INVALID);
   2.704 +
   2.705 +	  ++bucket_num;
   2.706 +	  
   2.707 +	  std::vector<Node> queue;
   2.708 +	  queue.push_back(t);
   2.709 +	  reached.set(t, true);
   2.710 +	  
   2.711 +	  while (!queue.empty()) {
   2.712 +	    _sets.front().push_front(bucket_num);
   2.713 +	    _dormant[bucket_num] = !first_set;
   2.714 +	    _first[bucket_num] = _last[bucket_num] = INVALID;
   2.715 +	    
   2.716 +	    std::vector<Node> nqueue;
   2.717 +	    for (int i = 0; i < int(queue.size()); ++i) {
   2.718 +	      Node n = queue[i];
   2.719 +	      for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.720 +		Node u = _graph.target(e);
   2.721 +		if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
   2.722 +		  reached.set(u, true);
   2.723 +		  addItem(u, bucket_num);
   2.724 +		  nqueue.push_back(u);
   2.725 +		}
   2.726 +	      }
   2.727 +	    }
   2.728 +	    queue.swap(nqueue);
   2.729 +	    ++bucket_num;
   2.730 +	  }
   2.731 +	  _sets.front().pop_front();
   2.732 +	  --bucket_num;
   2.733 +	  first_set = false;
   2.734 +	}
   2.735 +
   2.736 +	_bucket->set(_source, 0);
   2.737 +	_dormant[0] = true;
   2.738 +      }
   2.739 +      _source_set->set(_source, true);	  
   2.740 +	  
   2.741 +      Node target = _last[_sets.back().back()];
   2.742 +      {
   2.743 +	for (InEdgeIt e(_graph, _source); e != INVALID; ++e) {
   2.744 +	  if (_tolerance.positive((*_capacity)[e])) {
   2.745 +	    Node u = _graph.source(e);
   2.746 +	    _flow->set(e, (*_capacity)[e]);
   2.747 +	    _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
   2.748 +	    if (!(*_active)[u] && u != _source) {
   2.749 +	      activate(u);
   2.750 +	    }
   2.751 +	  }
   2.752 +	}
   2.753 +	if ((*_active)[target]) {
   2.754 +	  deactivate(target);
   2.755 +	}
   2.756 +	
   2.757 +	_highest = _sets.back().begin();
   2.758 +	while (_highest != _sets.back().end() && 
   2.759 +	       !(*_active)[_first[*_highest]]) {
   2.760 +	  ++_highest;
   2.761 +	}
   2.762 +      }
   2.763 +
   2.764 +
   2.765 +      while (true) {
   2.766 +	while (_highest != _sets.back().end()) {
   2.767 +	  Node n = _first[*_highest];
   2.768 +	  Value excess = (*_excess)[n];
   2.769 +	  int next_bucket = _node_num;
   2.770 +
   2.771 +	  int under_bucket;
   2.772 +	  if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
   2.773 +	    under_bucket = -1;
   2.774 +	  } else {
   2.775 +	    under_bucket = *(++std::list<int>::iterator(_highest));
   2.776 +	  }
   2.777 +
   2.778 +	  for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.779 +	    Node v = _graph.source(e);
   2.780 +	    if (_dormant[(*_bucket)[v]]) continue;
   2.781 +	    Value rem = (*_capacity)[e] - (*_flow)[e];
   2.782 +	    if (!_tolerance.positive(rem)) continue;
   2.783 +	    if ((*_bucket)[v] == under_bucket) {
   2.784 +	      if (!(*_active)[v] && v != target) {
   2.785 +		activate(v);
   2.786 +	      }
   2.787 +	      if (!_tolerance.less(rem, excess)) {
   2.788 +		_flow->set(e, (*_flow)[e] + excess);
   2.789 +		_excess->set(v, (*_excess)[v] + excess);
   2.790 +		excess = 0;
   2.791 +		goto no_more_push;
   2.792 +	      } else {
   2.793 +		excess -= rem;
   2.794 +		_excess->set(v, (*_excess)[v] + rem);
   2.795 +		_flow->set(e, (*_capacity)[e]);
   2.796 +	      }
   2.797 +	    } else if (next_bucket > (*_bucket)[v]) {
   2.798 +	      next_bucket = (*_bucket)[v];
   2.799 +	    }
   2.800 +	  }
   2.801 +
   2.802 +	  for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
   2.803 +	    Node v = _graph.target(e);
   2.804 +	    if (_dormant[(*_bucket)[v]]) continue;
   2.805 +	    Value rem = (*_flow)[e];
   2.806 +	    if (!_tolerance.positive(rem)) continue;
   2.807 +	    if ((*_bucket)[v] == under_bucket) {
   2.808 +	      if (!(*_active)[v] && v != target) {
   2.809 +		activate(v);
   2.810 +	      }
   2.811 +	      if (!_tolerance.less(rem, excess)) {
   2.812 +		_flow->set(e, (*_flow)[e] - excess);
   2.813 +		_excess->set(v, (*_excess)[v] + excess);
   2.814 +		excess = 0;
   2.815 +		goto no_more_push;
   2.816 +	      } else {
   2.817 +		excess -= rem;
   2.818 +		_excess->set(v, (*_excess)[v] + rem);
   2.819 +		_flow->set(e, 0);
   2.820 +	      }
   2.821 +	    } else if (next_bucket > (*_bucket)[v]) {
   2.822 +	      next_bucket = (*_bucket)[v];
   2.823 +	    }
   2.824 +	  }
   2.825 +	  
   2.826 +	no_more_push:
   2.827 +	  
   2.828 +	  _excess->set(n, excess);
   2.829 +	  
   2.830 +	  if (excess != 0) {
   2.831 +	    if ((*_next)[n] == INVALID) {
   2.832 +	      typename std::list<std::list<int> >::iterator new_set = 
   2.833 +		_sets.insert(--_sets.end(), std::list<int>());
   2.834 +	      new_set->splice(new_set->end(), _sets.back(), 
   2.835 +			      _sets.back().begin(), ++_highest);
   2.836 +	      for (std::list<int>::iterator it = new_set->begin();
   2.837 +		   it != new_set->end(); ++it) {
   2.838 +		_dormant[*it] = true;
   2.839 +	      }
   2.840 +	      while (_highest != _sets.back().end() && 
   2.841 +		     !(*_active)[_first[*_highest]]) {
   2.842 +		++_highest;
   2.843 +	      }
   2.844 +	    } else if (next_bucket == _node_num) {
   2.845 +	      _first[(*_bucket)[n]] = (*_next)[n];
   2.846 +	      _prev->set((*_next)[n], INVALID);
   2.847 +	      
   2.848 +	      std::list<std::list<int> >::iterator new_set = 
   2.849 +		_sets.insert(--_sets.end(), std::list<int>());
   2.850 +	      
   2.851 +	      new_set->push_front(bucket_num);
   2.852 +	      _bucket->set(n, bucket_num);
   2.853 +	      _first[bucket_num] = _last[bucket_num] = n;
   2.854 +	      _next->set(n, INVALID);
   2.855 +	      _prev->set(n, INVALID);
   2.856 +	      _dormant[bucket_num] = true;
   2.857 +	      ++bucket_num;
   2.858 +
   2.859 +	      while (_highest != _sets.back().end() && 
   2.860 +		     !(*_active)[_first[*_highest]]) {
   2.861 +		++_highest;
   2.862 +	      }
   2.863 +	    } else {
   2.864 +	      _first[*_highest] = (*_next)[n];
   2.865 +	      _prev->set((*_next)[n], INVALID);
   2.866 +
   2.867 +	      while (next_bucket != *_highest) {
   2.868 +		--_highest;
   2.869 +	      }
   2.870 +	      if (_highest == _sets.back().begin()) {
   2.871 +		_sets.back().push_front(bucket_num);
   2.872 +		_dormant[bucket_num] = false;
   2.873 +		_first[bucket_num] = _last[bucket_num] = INVALID;
   2.874 +		++bucket_num;
   2.875 +	      }
   2.876 +	      --_highest;
   2.877 +
   2.878 +	      _bucket->set(n, *_highest);
   2.879 +	      _next->set(n, _first[*_highest]);
   2.880 +	      if (_first[*_highest] != INVALID) {
   2.881 +		_prev->set(_first[*_highest], n);
   2.882 +	      } else {
   2.883 +		_last[*_highest] = n;
   2.884 +	      }
   2.885 +	      _first[*_highest] = n;	      
   2.886 +	    }
   2.887 +	  } else {
   2.888 +
   2.889 +	    deactivate(n);
   2.890 +	    if (!(*_active)[_first[*_highest]]) {
   2.891 +	      ++_highest;
   2.892 +	      if (_highest != _sets.back().end() && 
   2.893 +		  !(*_active)[_first[*_highest]]) {
   2.894 +		_highest = _sets.back().end();
   2.895 +	      }
   2.896 +	    }
   2.897 +	  }
   2.898 +	}
   2.899 +
   2.900 +	if ((*_excess)[target] < _min_cut) {
   2.901 +	  _min_cut = (*_excess)[target];
   2.902 +	  for (NodeIt i(_graph); i != INVALID; ++i) {
   2.903 +	    _min_cut_map->set(i, false);
   2.904 +	  }
   2.905 +	  for (std::list<int>::iterator it = _sets.back().begin();
   2.906 +	       it != _sets.back().end(); ++it) {
   2.907 +	    Node n = _first[*it];
   2.908 +	    while (n != INVALID) {
   2.909 +	      _min_cut_map->set(n, true);
   2.910 +	      n = (*_next)[n];
   2.911 +	    }
   2.912 +	  }
   2.913 +	}
   2.914 +
   2.915 +	{
   2.916 +	  Node new_target;
   2.917 +	  if ((*_prev)[target] != INVALID) {
   2.918 +	    _last[(*_bucket)[target]] = (*_prev)[target];
   2.919 +	    _next->set((*_prev)[target], INVALID);
   2.920 +	    new_target = (*_prev)[target];
   2.921 +	  } else {
   2.922 +	    _sets.back().pop_back();
   2.923 +	    if (_sets.back().empty()) {
   2.924 +	      _sets.pop_back();
   2.925 +	      if (_sets.empty())
   2.926 +		break;
   2.927 +	      for (std::list<int>::iterator it = _sets.back().begin();
   2.928 +		   it != _sets.back().end(); ++it) {
   2.929 +		_dormant[*it] = false;
   2.930 +	      }
   2.931 +	    }
   2.932 +	    new_target = _last[_sets.back().back()];
   2.933 +	  }
   2.934 +
   2.935 +	  _bucket->set(target, 0);
   2.936 +
   2.937 +	  _source_set->set(target, true);	  
   2.938 +	  for (InEdgeIt e(_graph, target); e != INVALID; ++e) {
   2.939 +	    Value rem = (*_capacity)[e] - (*_flow)[e];
   2.940 +	    if (!_tolerance.positive(rem)) continue;
   2.941 +	    Node v = _graph.source(e);
   2.942 +	    if (!(*_active)[v] && !(*_source_set)[v]) {
   2.943 +	      activate(v);
   2.944 +	    }
   2.945 +	    _excess->set(v, (*_excess)[v] + rem);
   2.946 +	    _flow->set(e, (*_capacity)[e]);
   2.947 +	  }
   2.948 +	  
   2.949 +	  for (OutEdgeIt e(_graph, target); e != INVALID; ++e) {
   2.950 +	    Value rem = (*_flow)[e];
   2.951 +	    if (!_tolerance.positive(rem)) continue;
   2.952 +	    Node v = _graph.target(e);
   2.953 +	    if (!(*_active)[v] && !(*_source_set)[v]) {
   2.954 +	      activate(v);
   2.955 +	    }
   2.956 +	    _excess->set(v, (*_excess)[v] + rem);
   2.957 +	    _flow->set(e, 0);
   2.958 +	  }
   2.959 +	  
   2.960 +	  target = new_target;
   2.961 +	  if ((*_active)[target]) {
   2.962 +	    deactivate(target);
   2.963 +	  }
   2.964 +
   2.965 +	  _highest = _sets.back().begin();
   2.966 +	  while (_highest != _sets.back().end() && 
   2.967 +		 !(*_active)[_first[*_highest]]) {
   2.968 +	    ++_highest;
   2.969 +	  }
   2.970  	}
   2.971        }
   2.972      }
   2.973  
   2.974 -    template <typename ResGraph>
   2.975 -    bool selectNewSink(ResGraph& res_graph) {
   2.976 -      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
   2.977 -
   2.978 -      Node old_target = _target;
   2.979 -      (*_wake)[_target] = false;
   2.980 -      --_level_size[(*_dist)[_target]];
   2.981 -      _dormant[0].push_front(_target);
   2.982 -      (*_source_set)[_target] = true;
   2.983 -      if (int(_dormant[0].size()) == _node_num){
   2.984 -        _dormant[0].clear();
   2.985 -	return false;
   2.986 -      }
   2.987 -
   2.988 -      bool wake_was_empty = false;
   2.989 -
   2.990 -      if(_wake->trueNum() == 0) {
   2.991 -	while (!_dormant[_dormant_max].empty()){
   2.992 -	  (*_wake)[_dormant[_dormant_max].front()] = true;
   2.993 -	  ++_level_size[(*_dist)[_dormant[_dormant_max].front()]];
   2.994 -	  _dormant[_dormant_max].pop_front();
   2.995 -	}
   2.996 -	--_dormant_max;
   2.997 -	wake_was_empty = true;
   2.998 -      }
   2.999 -
  2.1000 -      int min_dist = std::numeric_limits<int>::max();
  2.1001 -      for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
  2.1002 -	if (min_dist > (*_dist)[it]){
  2.1003 -	  _target = it;
  2.1004 -	  min_dist = (*_dist)[it];
  2.1005 -	}
  2.1006 -      }
  2.1007 -
  2.1008 -      if (wake_was_empty){
  2.1009 -	for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
  2.1010 -          if ((*_excess)[it] != 0 && it != _target) {
  2.1011 -            _active_nodes[(*_dist)[it]].push_front(it);
  2.1012 -            if (_highest_active < (*_dist)[it]) {
  2.1013 -              _highest_active = (*_dist)[it];		    
  2.1014 -            }
  2.1015 -	  }
  2.1016 -	}
  2.1017 -      }
  2.1018 -
  2.1019 -      Node n = old_target;
  2.1020 -      for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e){
  2.1021 -        Node a = res_graph.target(e);
  2.1022 -	if (!(*_wake)[a]) continue;
  2.1023 -        Value delta = res_graph.rescap(e);
  2.1024 -        res_graph.augment(e, delta);
  2.1025 -        (*_excess)[n] -= delta;
  2.1026 -        if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
  2.1027 -          _active_nodes[(*_dist)[a]].push_front(a);
  2.1028 -          if (_highest_active < (*_dist)[a]) {
  2.1029 -            _highest_active = (*_dist)[a];
  2.1030 -          }
  2.1031 -        }
  2.1032 -        (*_excess)[a] += delta;
  2.1033 -      }
  2.1034 -      
  2.1035 -      return true;
  2.1036 -    }
  2.1037 -
  2.1038 -    Node findActiveNode() {
  2.1039 -      while (_highest_active > 0 && _active_nodes[_highest_active].empty()){ 
  2.1040 -	--_highest_active;
  2.1041 -      }
  2.1042 -      if( _highest_active > 0) {
  2.1043 -       	Node n = _active_nodes[_highest_active].front();
  2.1044 -	_active_nodes[_highest_active].pop_front();
  2.1045 -	return n;
  2.1046 -      } else {
  2.1047 -	return INVALID;
  2.1048 -      }
  2.1049 -    }
  2.1050 -
  2.1051 -    Value cutValue(bool out) {
  2.1052 -      Value value = 0;
  2.1053 -      if (out) {
  2.1054 -        for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
  2.1055 -          for (InEdgeIt e(*_graph, it); e != INVALID; ++e) {
  2.1056 -            if (!(*_wake)[_graph->source(e)]){
  2.1057 -              value += (*_capacity)[e];
  2.1058 -            }	
  2.1059 -          }
  2.1060 -        }
  2.1061 -      } else {
  2.1062 -        for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
  2.1063 -          for (OutEdgeIt e(*_graph, it); e != INVALID; ++e) {
  2.1064 -            if (!(*_wake)[_graph->target(e)]){
  2.1065 -              value += (*_capacity)[e];
  2.1066 -            }	
  2.1067 -          }
  2.1068 -        }
  2.1069 -      }
  2.1070 -      return value;
  2.1071 -    }
  2.1072 -
  2.1073 -
  2.1074    public:
  2.1075  
  2.1076      /// \name Execution control
  2.1077 @@ -435,7 +836,7 @@
  2.1078      /// the maps, residual graph adaptors and some bucket structures
  2.1079      /// for the algorithm. 
  2.1080      void init() {
  2.1081 -      init(NodeIt(*_graph));
  2.1082 +      init(NodeIt(_graph));
  2.1083      }
  2.1084  
  2.1085      /// \brief Initializes the internal data structures.
  2.1086 @@ -446,38 +847,37 @@
  2.1087      /// algorithm's source.
  2.1088      void init(const Node& source) {
  2.1089        _source = source;
  2.1090 -      _node_num = countNodes(*_graph);
  2.1091 +      
  2.1092 +      _node_num = countNodes(_graph);
  2.1093 +      
  2.1094 +      _first.resize(_node_num);
  2.1095 +      _last.resize(_node_num);
  2.1096  
  2.1097        _dormant.resize(_node_num);
  2.1098 -      _level_size.resize(_node_num, 0);
  2.1099 -      _active_nodes.resize(_node_num);
  2.1100  
  2.1101 -      if (!_preflow) {
  2.1102 -        _preflow = new FlowMap(*_graph);
  2.1103 +      if (!_flow) {
  2.1104 +	_flow = new FlowMap(_graph);
  2.1105        }
  2.1106 -      if (!_wake) {
  2.1107 -        _wake = new WakeMap(*_graph);
  2.1108 +      if (!_next) {
  2.1109 +	_next = new typename Graph::template NodeMap<Node>(_graph);
  2.1110        }
  2.1111 -      if (!_dist) {
  2.1112 -        _dist = new DistMap(*_graph);
  2.1113 +      if (!_prev) {
  2.1114 +	_prev = new typename Graph::template NodeMap<Node>(_graph);
  2.1115 +      }
  2.1116 +      if (!_active) {
  2.1117 +	_active = new typename Graph::template NodeMap<bool>(_graph);
  2.1118 +      }
  2.1119 +      if (!_bucket) {
  2.1120 +	_bucket = new typename Graph::template NodeMap<int>(_graph);
  2.1121        }
  2.1122        if (!_excess) {
  2.1123 -        _excess = new ExcessMap(*_graph);
  2.1124 +	_excess = new ExcessMap(_graph);
  2.1125        }
  2.1126        if (!_source_set) {
  2.1127 -        _source_set = new SourceSetMap(*_graph);
  2.1128 -      }
  2.1129 -      if (!_out_res_graph) {
  2.1130 -        _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow);
  2.1131 -      }
  2.1132 -      if (!_rev_graph) {
  2.1133 -        _rev_graph = new RevGraph(*_graph);
  2.1134 -      }
  2.1135 -      if (!_in_res_graph) {
  2.1136 -        _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow);
  2.1137 +	_source_set = new SourceSetMap(_graph);
  2.1138        }
  2.1139        if (!_min_cut_map) {
  2.1140 -        _min_cut_map = new MinCutMap(*_graph);
  2.1141 +	_min_cut_map = new MinCutMap(_graph);
  2.1142        }
  2.1143  
  2.1144        _min_cut = std::numeric_limits<Value>::max();
  2.1145 @@ -487,56 +887,23 @@
  2.1146      /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1147      /// source-side.
  2.1148      ///
  2.1149 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1150 -    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$
  2.1151 -    ///  and minimal out-degree).
  2.1152 +    /// Calculates a minimum cut with \f$ source \f$ on the
  2.1153 +    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source
  2.1154 +    /// \in X \f$ and minimal out-degree).
  2.1155      void calculateOut() {
  2.1156 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
  2.1157 -        if (it != _source) {
  2.1158 -          calculateOut(it);
  2.1159 -          return;
  2.1160 -        }
  2.1161 -      }
  2.1162 +      findMinCutOut();
  2.1163      }
  2.1164  
  2.1165      /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1166 -    /// source-side.
  2.1167 +    /// target-side.
  2.1168      ///
  2.1169 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1170 -    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$
  2.1171 -    ///  and minimal out-degree). The \c target is the initial target
  2.1172 -    /// for the push-relabel algorithm.
  2.1173 -    void calculateOut(const Node& target) {
  2.1174 -      findMinCut(target, true, *_out_res_graph);
  2.1175 +    /// Calculates a minimum cut with \f$ source \f$ on the
  2.1176 +    /// target-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source
  2.1177 +    /// \in X \f$ and minimal out-degree).
  2.1178 +    void calculateIn() {
  2.1179 +      findMinCutIn();
  2.1180      }
  2.1181  
  2.1182 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1183 -    /// sink-side.
  2.1184 -    ///
  2.1185 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1186 -    /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with 
  2.1187 -    /// \f$ source \notin X \f$
  2.1188 -    /// and minimal out-degree).
  2.1189 -    void calculateIn() {
  2.1190 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
  2.1191 -        if (it != _source) {
  2.1192 -          calculateIn(it);
  2.1193 -          return;
  2.1194 -        }
  2.1195 -      }
  2.1196 -    }
  2.1197 -
  2.1198 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1199 -    /// sink-side.
  2.1200 -    ///
  2.1201 -    /// \brief Calculates a minimum cut with \f$ source \f$ on the
  2.1202 -    /// sink-side (i.e. a set \f$ X\subsetneq V 
  2.1203 -    /// \f$ with \f$ source \notin X \f$ and minimal out-degree).  
  2.1204 -    /// The \c target is the initial
  2.1205 -    /// target for the push-relabel algorithm.
  2.1206 -    void calculateIn(const Node& target) {
  2.1207 -      findMinCut(target, false, *_in_res_graph);
  2.1208 -    }
  2.1209  
  2.1210      /// \brief Runs the algorithm.
  2.1211      ///
  2.1212 @@ -545,13 +912,8 @@
  2.1213      /// and \ref calculateIn().
  2.1214      void run() {
  2.1215        init();
  2.1216 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
  2.1217 -        if (it != _source) {
  2.1218 -          calculateOut(it);
  2.1219 -          calculateIn(it);
  2.1220 -          return;
  2.1221 -        }
  2.1222 -      }
  2.1223 +      calculateOut();
  2.1224 +      calculateIn();
  2.1225      }
  2.1226  
  2.1227      /// \brief Runs the algorithm.
  2.1228 @@ -561,23 +923,8 @@
  2.1229      /// calculateOut() and \ref calculateIn().
  2.1230      void run(const Node& s) {
  2.1231        init(s);
  2.1232 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
  2.1233 -        if (it != _source) {
  2.1234 -          calculateOut(it);
  2.1235 -          calculateIn(it);
  2.1236 -          return;
  2.1237 -        }
  2.1238 -      }
  2.1239 -    }
  2.1240 -
  2.1241 -    /// \brief Runs the algorithm.
  2.1242 -    ///
  2.1243 -    /// Runs the algorithm. It just calls the \ref init() and then
  2.1244 -    /// \ref calculateOut() and \ref calculateIn().
  2.1245 -    void run(const Node& s, const Node& t) {
  2.1246 -      init(s); 
  2.1247 -      calculateOut(t);
  2.1248 -      calculateIn(t);
  2.1249 +      calculateOut();
  2.1250 +      calculateIn();
  2.1251      }
  2.1252  
  2.1253      /// @}
  2.1254 @@ -608,7 +955,7 @@
  2.1255      /// bool-valued node-map.
  2.1256      template <typename NodeMap>
  2.1257      Value minCut(NodeMap& nodeMap) const {
  2.1258 -      for (NodeIt it(*_graph); it != INVALID; ++it) {
  2.1259 +      for (NodeIt it(_graph); it != INVALID; ++it) {
  2.1260  	nodeMap.set(it, (*_min_cut_map)[it]);
  2.1261        }
  2.1262        return minCut();
     3.1 --- a/lemon/nagamochi_ibaraki.h	Fri Nov 30 09:22:38 2007 +0000
     3.2 +++ b/lemon/nagamochi_ibaraki.h	Tue Dec 04 10:55:27 2007 +0000
     3.3 @@ -847,9 +847,9 @@
     3.4    /// distinict subnetwork.
     3.5    ///
     3.6    /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with
     3.7 -  /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$. 
     3.8 -  /// When capacity map is neutral then it uses BucketHeap which
     3.9 -  /// results \f$ O(ne) \f$ time complexity.
    3.10 +  /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
    3.11 +  /// When unit capacity minimum cut is computed then it uses
    3.12 +  /// BucketHeap which results \f$ O(ne) \f$ time complexity.
    3.13    ///
    3.14    /// \warning The value type of the capacity map should be able to hold
    3.15    /// any cut value of the graph, otherwise the result can overflow.
    3.16 @@ -906,7 +906,7 @@
    3.17  
    3.18      ///@{
    3.19  
    3.20 -    struct DefNeutralCapacityTraits : public Traits {
    3.21 +    struct DefUnitCapacityTraits : public Traits {
    3.22        typedef ConstMap<typename Graph::UEdge, Const<int, 1> > CapacityMap;
    3.23        static CapacityMap *createCapacityMap(const Graph&) {
    3.24  	return new CapacityMap();
    3.25 @@ -917,11 +917,11 @@
    3.26      ///
    3.27      /// \ref named-templ-param "Named parameter" for setting 
    3.28      /// the capacity type to constMap<UEdge, int, 1>()
    3.29 -    struct DefNeutralCapacity
    3.30 +    struct DefUnitCapacity
    3.31        : public NagamochiIbaraki<Graph, CapacityMap, 
    3.32 -                                DefNeutralCapacityTraits> { 
    3.33 +                                DefUnitCapacityTraits> { 
    3.34        typedef NagamochiIbaraki<Graph, CapacityMap, 
    3.35 -                               DefNeutralCapacityTraits> Create;
    3.36 +                               DefUnitCapacityTraits> Create;
    3.37      };
    3.38  
    3.39  
    3.40 @@ -1134,7 +1134,7 @@
    3.41      ///
    3.42      /// This constructor can be used only when the Traits class
    3.43      /// defines how can we instantiate a local capacity map.
    3.44 -    /// If the DefNeutralCapacity used the algorithm automatically
    3.45 +    /// If the DefUnitCapacity used the algorithm automatically
    3.46      /// construct the capacity map.
    3.47      ///
    3.48      ///\param graph the graph the algorithm will run on.