| marci@478 |      1 | // -*- C++ -*-
 | 
| alpar@921 |      2 | #ifndef LEMON_MAX_FLOW_H
 | 
| alpar@921 |      3 | #define LEMON_MAX_FLOW_H
 | 
| marci@478 |      4 | 
 | 
| marci@478 |      5 | #include <vector>
 | 
| marci@478 |      6 | #include <queue>
 | 
| marci@478 |      7 | #include <stack>
 | 
| marci@478 |      8 | 
 | 
| alpar@921 |      9 | #include <lemon/graph_wrapper.h>
 | 
| marci@602 |     10 | #include <bfs_dfs.h>
 | 
| alpar@921 |     11 | #include <lemon/invalid.h>
 | 
| alpar@921 |     12 | #include <lemon/maps.h>
 | 
| alpar@921 |     13 | #include <lemon/for_each_macros.h>
 | 
| marci@478 |     14 | 
 | 
| marci@488 |     15 | /// \file
 | 
| jacint@631 |     16 | /// \brief Maximum flow algorithms.
 | 
| marci@615 |     17 | /// \ingroup galgs
 | 
| marci@478 |     18 | 
 | 
| alpar@921 |     19 | namespace lemon {
 | 
| marci@478 |     20 | 
 | 
| jacint@631 |     21 |   /// \addtogroup galgs
 | 
| jacint@631 |     22 |   /// @{                                                                                                                                        
 | 
| jacint@631 |     23 |   ///Maximum flow algorithms class.
 | 
| marci@488 |     24 | 
 | 
| jacint@631 |     25 |   ///This class provides various algorithms for finding a flow of
 | 
| jacint@631 |     26 |   ///maximum value in a directed graph. The \e source node, the \e
 | 
| jacint@631 |     27 |   ///target node, the \e capacity of the edges and the \e starting \e
 | 
| marci@647 |     28 |   ///flow value of the edges should be passed to the algorithm through the
 | 
| jacint@631 |     29 |   ///constructor. It is possible to change these quantities using the
 | 
| jacint@631 |     30 |   ///functions \ref resetSource, \ref resetTarget, \ref resetCap and
 | 
| jacint@631 |     31 |   ///\ref resetFlow. Before any subsequent runs of any algorithm of
 | 
| marci@647 |     32 |   ///the class \ref resetFlow should be called. 
 | 
| marci@647 |     33 | 
 | 
| marci@647 |     34 |   ///After running an algorithm of the class, the actual flow value 
 | 
| marci@647 |     35 |   ///can be obtained by calling \ref flowValue(). The minimum
 | 
| jacint@631 |     36 |   ///value cut can be written into a \c node map of \c bools by
 | 
| jacint@631 |     37 |   ///calling \ref minCut. (\ref minMinCut and \ref maxMinCut writes
 | 
| jacint@631 |     38 |   ///the inclusionwise minimum and maximum of the minimum value
 | 
| jacint@631 |     39 |   ///cuts, resp.)                                                                                                                               
 | 
| marci@632 |     40 |   ///\param Graph The directed graph type the algorithm runs on.
 | 
| jacint@631 |     41 |   ///\param Num The number type of the capacities and the flow values.
 | 
| marci@647 |     42 |   ///\param CapMap The capacity map type.
 | 
| marci@647 |     43 |   ///\param FlowMap The flow map type.                                                                                                           
 | 
| jacint@631 |     44 |   ///\author Marton Makai, Jacint Szabo 
 | 
| marci@615 |     45 |   template <typename Graph, typename Num,
 | 
| marci@615 |     46 | 	    typename CapMap=typename Graph::template EdgeMap<Num>,
 | 
| marci@478 |     47 |             typename FlowMap=typename Graph::template EdgeMap<Num> >
 | 
| marci@478 |     48 |   class MaxFlow {
 | 
| marci@615 |     49 |   protected:
 | 
| marci@478 |     50 |     typedef typename Graph::Node Node;
 | 
| marci@478 |     51 |     typedef typename Graph::NodeIt NodeIt;
 | 
| jacint@631 |     52 |     typedef typename Graph::EdgeIt EdgeIt;
 | 
| marci@478 |     53 |     typedef typename Graph::OutEdgeIt OutEdgeIt;
 | 
| marci@478 |     54 |     typedef typename Graph::InEdgeIt InEdgeIt;
 | 
| marci@478 |     55 | 
 | 
| marci@478 |     56 |     typedef typename std::vector<std::stack<Node> > VecStack;
 | 
| marci@478 |     57 |     typedef typename Graph::template NodeMap<Node> NNMap;
 | 
| marci@478 |     58 |     typedef typename std::vector<Node> VecNode;
 | 
| marci@478 |     59 | 
 | 
| marci@478 |     60 |     const Graph* g;
 | 
| marci@478 |     61 |     Node s;
 | 
| marci@478 |     62 |     Node t;
 | 
| marci@615 |     63 |     const CapMap* capacity;
 | 
| marci@478 |     64 |     FlowMap* flow;
 | 
| marci@478 |     65 |     int n;      //the number of nodes of G
 | 
| marci@653 |     66 |     typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;   
 | 
| marci@653 |     67 |     //typedef ExpResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
 | 
| marci@478 |     68 |     typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
 | 
| marci@478 |     69 |     typedef typename ResGW::Edge ResGWEdge;
 | 
| marci@478 |     70 |     //typedef typename ResGW::template NodeMap<bool> ReachedMap;
 | 
| marci@478 |     71 |     typedef typename Graph::template NodeMap<int> ReachedMap;
 | 
| jacint@631 |     72 | 
 | 
| jacint@631 |     73 | 
 | 
| jacint@631 |     74 |     //level works as a bool map in augmenting path algorithms and is
 | 
| jacint@631 |     75 |     //used by bfs for storing reached information.  In preflow, it
 | 
| jacint@631 |     76 |     //shows the levels of nodes.     
 | 
| marci@478 |     77 |     ReachedMap level;
 | 
| jacint@631 |     78 | 
 | 
| jacint@631 |     79 |     //excess is needed only in preflow
 | 
| marci@615 |     80 |     typename Graph::template NodeMap<Num> excess;
 | 
| jacint@631 |     81 | 
 | 
| jacint@631 |     82 |     //fixme    
 | 
| jacint@631 |     83 | //   protected:
 | 
| marci@602 |     84 |     //     MaxFlow() { }
 | 
| marci@615 |     85 |     //     void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
 | 
| marci@615 |     86 |     // 	     FlowMap& _flow)
 | 
| marci@602 |     87 |     //       {
 | 
| marci@615 |     88 |     // 	g=&_G;
 | 
| marci@615 |     89 |     // 	s=_s;
 | 
| marci@615 |     90 |     // 	t=_t;
 | 
| marci@602 |     91 |     // 	capacity=&_capacity;
 | 
| marci@602 |     92 |     // 	flow=&_flow;
 | 
| marci@602 |     93 |     // 	n=_G.nodeNum;
 | 
| marci@615 |     94 |     // 	level.set (_G); //kellene vmi ilyesmi fv
 | 
| marci@602 |     95 |     // 	excess(_G,0); //itt is
 | 
| marci@602 |     96 |     //       }
 | 
| marci@478 |     97 | 
 | 
| marci@615 |     98 |     // constants used for heuristics
 | 
| marci@615 |     99 |     static const int H0=20;
 | 
| marci@615 |    100 |     static const int H1=1;
 | 
| marci@615 |    101 | 
 | 
| marci@478 |    102 |   public:
 | 
| marci@615 |    103 | 
 | 
| jacint@631 |    104 |     ///Indicates the property of the starting flow.
 | 
| jacint@631 |    105 | 
 | 
| jacint@631 |    106 |     ///Indicates the property of the starting flow. The meanings are as follows:
 | 
| jacint@631 |    107 |     ///- \c ZERO_FLOW: constant zero flow
 | 
| jacint@631 |    108 |     ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
 | 
| jacint@631 |    109 |     ///the sum of the out-flows in every node except the \e source and
 | 
| jacint@631 |    110 |     ///the \e target.
 | 
| jacint@631 |    111 |     ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at 
 | 
| jacint@631 |    112 |     ///least the sum of the out-flows in every node except the \e source.
 | 
| jacint@631 |    113 |     ///- \c NO_FLOW: indicates an unspecified edge map. \ref flow will be 
 | 
| jacint@631 |    114 |     ///set to the constant zero flow in the beginning of the algorithm in this case.
 | 
| marci@647 |    115 |     enum FlowEnum{
 | 
| marci@615 |    116 |       ZERO_FLOW,
 | 
| marci@615 |    117 |       GEN_FLOW,
 | 
| marci@615 |    118 |       PRE_FLOW,
 | 
| marci@615 |    119 |       NO_FLOW
 | 
| marci@478 |    120 |     };
 | 
| marci@478 |    121 | 
 | 
| marci@647 |    122 |     enum StatusEnum {
 | 
| marci@647 |    123 |       AFTER_NOTHING,
 | 
| marci@647 |    124 |       AFTER_AUGMENTING,
 | 
| marci@656 |    125 |       AFTER_FAST_AUGMENTING, 
 | 
| marci@647 |    126 |       AFTER_PRE_FLOW_PHASE_1,      
 | 
| marci@647 |    127 |       AFTER_PRE_FLOW_PHASE_2
 | 
| marci@647 |    128 |     };
 | 
| marci@647 |    129 | 
 | 
| marci@647 |    130 |     /// Don not needle this flag only if necessary.
 | 
| marci@647 |    131 |     StatusEnum status;
 | 
| marci@647 |    132 |     int number_of_augmentations;
 | 
| marci@647 |    133 | 
 | 
| marci@647 |    134 | 
 | 
| marci@647 |    135 |     template<typename IntMap>
 | 
| marci@647 |    136 |     class TrickyReachedMap {
 | 
| marci@647 |    137 |     protected:
 | 
| marci@647 |    138 |       IntMap* map;
 | 
| marci@647 |    139 |       int* number_of_augmentations;
 | 
| marci@647 |    140 |     public:
 | 
| marci@647 |    141 |       TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) : 
 | 
| marci@647 |    142 | 	map(&_map), number_of_augmentations(&_number_of_augmentations) { }
 | 
| marci@647 |    143 |       void set(const Node& n, bool b) {
 | 
| marci@650 |    144 | 	if (b)
 | 
| marci@650 |    145 | 	  map->set(n, *number_of_augmentations);
 | 
| marci@650 |    146 | 	else 
 | 
| marci@650 |    147 | 	  map->set(n, *number_of_augmentations-1);
 | 
| marci@647 |    148 |       }
 | 
| marci@647 |    149 |       bool operator[](const Node& n) const { 
 | 
| marci@647 |    150 | 	return (*map)[n]==*number_of_augmentations; 
 | 
| marci@647 |    151 |       }
 | 
| marci@647 |    152 |     };
 | 
| marci@647 |    153 |     
 | 
| alpar@709 |    154 |     ///Constructor
 | 
| alpar@709 |    155 | 
 | 
| alpar@709 |    156 |     ///\todo Document, please.
 | 
| alpar@709 |    157 |     ///
 | 
| marci@615 |    158 |     MaxFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
 | 
| marci@478 |    159 | 	    FlowMap& _flow) :
 | 
| marci@615 |    160 |       g(&_G), s(_s), t(_t), capacity(&_capacity),
 | 
| marci@647 |    161 |       flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0), 
 | 
| marci@647 |    162 |       status(AFTER_NOTHING), number_of_augmentations(0) { }
 | 
| marci@478 |    163 | 
 | 
| jacint@631 |    164 |     ///Runs a maximum flow algorithm.
 | 
| jacint@631 |    165 | 
 | 
| jacint@631 |    166 |     ///Runs a preflow algorithm, which is the fastest maximum flow
 | 
| jacint@631 |    167 |     ///algorithm up-to-date. The default for \c fe is ZERO_FLOW.
 | 
| jacint@631 |    168 |     ///\pre The starting flow must be
 | 
| jacint@631 |    169 |     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
 | 
| jacint@631 |    170 |     /// - an arbitary flow if \c fe is \c GEN_FLOW,
 | 
| jacint@631 |    171 |     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
 | 
| jacint@631 |    172 |     /// - any map if \c fe is NO_FLOW.
 | 
| marci@647 |    173 |     void run(FlowEnum fe=ZERO_FLOW) {
 | 
| marci@615 |    174 |       preflow(fe);
 | 
| marci@478 |    175 |     }
 | 
| marci@615 |    176 | 
 | 
| marci@647 |    177 |                                                                               
 | 
| jacint@631 |    178 |     ///Runs a preflow algorithm.  
 | 
| jacint@631 |    179 | 
 | 
| jacint@631 |    180 |     ///Runs a preflow algorithm. The preflow algorithms provide the
 | 
| jacint@631 |    181 |     ///fastest way to compute a maximum flow in a directed graph.
 | 
| jacint@631 |    182 |     ///\pre The starting flow must be
 | 
| jacint@631 |    183 |     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
 | 
| jacint@631 |    184 |     /// - an arbitary flow if \c fe is \c GEN_FLOW,
 | 
| jacint@631 |    185 |     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
 | 
| jacint@631 |    186 |     /// - any map if \c fe is NO_FLOW.
 | 
| alpar@709 |    187 |     ///
 | 
| alpar@709 |    188 |     ///\todo NO_FLOW should be the default flow.
 | 
| marci@647 |    189 |     void preflow(FlowEnum fe) {
 | 
| jacint@631 |    190 |       preflowPhase1(fe);
 | 
| jacint@631 |    191 |       preflowPhase2();
 | 
| marci@478 |    192 |     }
 | 
| jacint@631 |    193 |     // Heuristics:
 | 
| jacint@631 |    194 |     //   2 phase
 | 
| jacint@631 |    195 |     //   gap
 | 
| jacint@631 |    196 |     //   list 'level_list' on the nodes on level i implemented by hand
 | 
| jacint@631 |    197 |     //   stack 'active' on the active nodes on level i                                                                                    
 | 
| jacint@631 |    198 |     //   runs heuristic 'highest label' for H1*n relabels
 | 
| jacint@631 |    199 |     //   runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
 | 
| jacint@631 |    200 |     //   Parameters H0 and H1 are initialized to 20 and 1.
 | 
| marci@478 |    201 | 
 | 
| jacint@631 |    202 |     ///Runs the first phase of the preflow algorithm.
 | 
| marci@478 |    203 | 
 | 
| jacint@631 |    204 |     ///The preflow algorithm consists of two phases, this method runs the
 | 
| jacint@631 |    205 |     ///first phase. After the first phase the maximum flow value and a
 | 
| jacint@631 |    206 |     ///minimum value cut can already be computed, though a maximum flow
 | 
| jacint@631 |    207 |     ///is net yet obtained. So after calling this method \ref flowValue
 | 
| jacint@631 |    208 |     ///and \ref actMinCut gives proper results.
 | 
| jacint@631 |    209 |     ///\warning: \ref minCut, \ref minMinCut and \ref maxMinCut do not
 | 
| jacint@631 |    210 |     ///give minimum value cuts unless calling \ref preflowPhase2.
 | 
| jacint@631 |    211 |     ///\pre The starting flow must be
 | 
| jacint@631 |    212 |     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
 | 
| jacint@631 |    213 |     /// - an arbitary flow if \c fe is \c GEN_FLOW,
 | 
| jacint@631 |    214 |     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
 | 
| jacint@631 |    215 |     /// - any map if \c fe is NO_FLOW.
 | 
| marci@647 |    216 |     void preflowPhase1(FlowEnum fe);
 | 
| jacint@631 |    217 | 
 | 
| jacint@631 |    218 |     ///Runs the second phase of the preflow algorithm.
 | 
| jacint@631 |    219 | 
 | 
| jacint@631 |    220 |     ///The preflow algorithm consists of two phases, this method runs
 | 
| jacint@631 |    221 |     ///the second phase. After calling \ref preflowPhase1 and then
 | 
| jacint@631 |    222 |     ///\ref preflowPhase2 the methods \ref flowValue, \ref minCut,
 | 
| jacint@631 |    223 |     ///\ref minMinCut and \ref maxMinCut give proper results.
 | 
| jacint@631 |    224 |     ///\pre \ref preflowPhase1 must be called before.
 | 
| jacint@631 |    225 |     void preflowPhase2();
 | 
| marci@478 |    226 | 
 | 
| marci@615 |    227 |     /// Starting from a flow, this method searches for an augmenting path
 | 
| marci@615 |    228 |     /// according to the Edmonds-Karp algorithm
 | 
| marci@615 |    229 |     /// and augments the flow on if any.
 | 
| marci@487 |    230 |     /// The return value shows if the augmentation was succesful.
 | 
| marci@478 |    231 |     bool augmentOnShortestPath();
 | 
| marci@647 |    232 |     bool augmentOnShortestPath2();
 | 
| marci@478 |    233 | 
 | 
| marci@615 |    234 |     /// Starting from a flow, this method searches for an augmenting blocking
 | 
| marci@615 |    235 |     /// flow according to Dinits' algorithm and augments the flow on if any.
 | 
| marci@615 |    236 |     /// The blocking flow is computed in a physically constructed
 | 
| marci@485 |    237 |     /// residual graph of type \c Mutablegraph.
 | 
| marci@487 |    238 |     /// The return value show sif the augmentation was succesful.
 | 
| marci@478 |    239 |     template<typename MutableGraph> bool augmentOnBlockingFlow();
 | 
| marci@478 |    240 | 
 | 
| marci@615 |    241 |     /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
 | 
| marci@485 |    242 |     /// residual graph is not constructed physically.
 | 
| marci@487 |    243 |     /// The return value shows if the augmentation was succesful.
 | 
| marci@478 |    244 |     bool augmentOnBlockingFlow2();
 | 
| marci@478 |    245 | 
 | 
| jacint@631 |    246 |     /// Returns the maximum value of a flow.
 | 
| jacint@631 |    247 | 
 | 
| jacint@631 |    248 |     /// Returns the maximum value of a flow, by counting the 
 | 
| jacint@631 |    249 |     /// over-flow of the target node \ref t.
 | 
| jacint@631 |    250 |     /// It can be called already after running \ref preflowPhase1.
 | 
| marci@647 |    251 |     Num flowValue() const {
 | 
| marci@478 |    252 |       Num a=0;
 | 
| marci@615 |    253 |       FOR_EACH_INC_LOC(InEdgeIt, e, *g, t) a+=(*flow)[e];
 | 
| marci@615 |    254 |       FOR_EACH_INC_LOC(OutEdgeIt, e, *g, t) a-=(*flow)[e];
 | 
| marci@478 |    255 |       return a;
 | 
| jacint@631 |    256 |       //marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan   
 | 
| marci@478 |    257 |     }
 | 
| marci@478 |    258 | 
 | 
| jacint@631 |    259 |     ///Returns a minimum value cut after calling \ref preflowPhase1.
 | 
| jacint@631 |    260 | 
 | 
| jacint@631 |    261 |     ///After the first phase of the preflow algorithm the maximum flow
 | 
| jacint@631 |    262 |     ///value and a minimum value cut can already be computed. This
 | 
| jacint@631 |    263 |     ///method can be called after running \ref preflowPhase1 for
 | 
| jacint@631 |    264 |     ///obtaining a minimum value cut.
 | 
| jacint@631 |    265 |     /// \warning Gives proper result only right after calling \ref
 | 
| jacint@631 |    266 |     /// preflowPhase1.
 | 
| marci@615 |    267 |     /// \todo We have to make some status variable which shows the
 | 
| marci@615 |    268 |     /// actual state
 | 
| marci@615 |    269 |     /// of the class. This enables us to determine which methods are valid
 | 
| marci@485 |    270 |     /// for MinCut computation
 | 
| marci@478 |    271 |     template<typename _CutMap>
 | 
| marci@647 |    272 |     void actMinCut(_CutMap& M) const {
 | 
| marci@478 |    273 |       NodeIt v;
 | 
| marci@647 |    274 |       switch (status) {
 | 
| marci@656 |    275 |       case AFTER_PRE_FLOW_PHASE_1:
 | 
| marci@647 |    276 | 	for(g->first(v); g->valid(v); g->next(v)) {
 | 
| marci@647 |    277 | 	  if (level[v] < n) {
 | 
| marci@647 |    278 | 	    M.set(v, false);
 | 
| marci@647 |    279 | 	  } else {
 | 
| marci@647 |    280 | 	    M.set(v, true);
 | 
| marci@647 |    281 | 	  }
 | 
| marci@485 |    282 | 	}
 | 
| marci@647 |    283 | 	break;
 | 
| marci@656 |    284 |       case AFTER_PRE_FLOW_PHASE_2:
 | 
| marci@656 |    285 |       case AFTER_NOTHING:
 | 
| marci@647 |    286 | 	minMinCut(M);
 | 
| marci@647 |    287 | 	break;
 | 
| marci@656 |    288 |       case AFTER_AUGMENTING:
 | 
| marci@647 |    289 | 	for(g->first(v); g->valid(v); g->next(v)) {
 | 
| marci@647 |    290 | 	  if (level[v]) {
 | 
| marci@647 |    291 | 	    M.set(v, true);
 | 
| marci@647 |    292 | 	  } else {
 | 
| marci@647 |    293 | 	    M.set(v, false);
 | 
| marci@647 |    294 | 	  }
 | 
| marci@647 |    295 | 	}
 | 
| marci@647 |    296 | 	break;
 | 
| marci@656 |    297 |       case AFTER_FAST_AUGMENTING:
 | 
| marci@656 |    298 | 	for(g->first(v); g->valid(v); g->next(v)) {
 | 
| marci@656 |    299 | 	  if (level[v]==number_of_augmentations) {
 | 
| marci@656 |    300 | 	    M.set(v, true);
 | 
| marci@656 |    301 | 	  } else {
 | 
| marci@656 |    302 | 	    M.set(v, false);
 | 
| marci@656 |    303 | 	  }
 | 
| marci@656 |    304 | 	}
 | 
| marci@656 |    305 | 	break;
 | 
| marci@478 |    306 |       }
 | 
| marci@478 |    307 |     }
 | 
| marci@478 |    308 | 
 | 
| jacint@631 |    309 |     ///Returns the inclusionwise minimum of the minimum value cuts.
 | 
| jacint@631 |    310 | 
 | 
| jacint@631 |    311 |     ///Sets \c M to the characteristic vector of the minimum value cut
 | 
| jacint@631 |    312 |     ///which is inclusionwise minimum. It is computed by processing
 | 
| jacint@631 |    313 |     ///a bfs from the source node \c s in the residual graph.
 | 
| jacint@631 |    314 |     ///\pre M should be a node map of bools initialized to false.
 | 
| jacint@631 |    315 |     ///\pre \c flow must be a maximum flow.
 | 
| marci@478 |    316 |     template<typename _CutMap>
 | 
| marci@647 |    317 |     void minMinCut(_CutMap& M) const {
 | 
| marci@478 |    318 |       std::queue<Node> queue;
 | 
| marci@615 |    319 | 
 | 
| marci@615 |    320 |       M.set(s,true);
 | 
| marci@478 |    321 |       queue.push(s);
 | 
| marci@478 |    322 | 
 | 
| marci@478 |    323 |       while (!queue.empty()) {
 | 
| marci@478 |    324 |         Node w=queue.front();
 | 
| marci@478 |    325 | 	queue.pop();
 | 
| marci@478 |    326 | 
 | 
| marci@478 |    327 | 	OutEdgeIt e;
 | 
| marci@478 |    328 | 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
 | 
| marci@478 |    329 | 	  Node v=g->head(e);
 | 
| marci@478 |    330 | 	  if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
 | 
| marci@478 |    331 | 	    queue.push(v);
 | 
| marci@478 |    332 | 	    M.set(v, true);
 | 
| marci@478 |    333 | 	  }
 | 
| marci@615 |    334 | 	}
 | 
| marci@478 |    335 | 
 | 
| marci@478 |    336 | 	InEdgeIt f;
 | 
| marci@478 |    337 | 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
 | 
| marci@478 |    338 | 	  Node v=g->tail(f);
 | 
| marci@478 |    339 | 	  if (!M[v] && (*flow)[f] > 0 ) {
 | 
| marci@478 |    340 | 	    queue.push(v);
 | 
| marci@478 |    341 | 	    M.set(v, true);
 | 
| marci@478 |    342 | 	  }
 | 
| marci@615 |    343 | 	}
 | 
| marci@478 |    344 |       }
 | 
| marci@478 |    345 |     }
 | 
| marci@478 |    346 | 
 | 
| jacint@631 |    347 |     ///Returns the inclusionwise maximum of the minimum value cuts.
 | 
| marci@478 |    348 | 
 | 
| jacint@631 |    349 |     ///Sets \c M to the characteristic vector of the minimum value cut
 | 
| jacint@631 |    350 |     ///which is inclusionwise maximum. It is computed by processing a
 | 
| jacint@631 |    351 |     ///backward bfs from the target node \c t in the residual graph.
 | 
| jacint@631 |    352 |     ///\pre M should be a node map of bools initialized to false.
 | 
| jacint@631 |    353 |     ///\pre \c flow must be a maximum flow. 
 | 
| marci@478 |    354 |     template<typename _CutMap>
 | 
| marci@647 |    355 |     void maxMinCut(_CutMap& M) const {
 | 
| marci@478 |    356 | 
 | 
| marci@478 |    357 |       NodeIt v;
 | 
| marci@478 |    358 |       for(g->first(v) ; g->valid(v); g->next(v)) {
 | 
| marci@478 |    359 | 	M.set(v, true);
 | 
| marci@478 |    360 |       }
 | 
| marci@478 |    361 | 
 | 
| marci@478 |    362 |       std::queue<Node> queue;
 | 
| marci@615 |    363 | 
 | 
| marci@615 |    364 |       M.set(t,false);
 | 
| marci@478 |    365 |       queue.push(t);
 | 
| marci@478 |    366 | 
 | 
| marci@478 |    367 |       while (!queue.empty()) {
 | 
| marci@478 |    368 |         Node w=queue.front();
 | 
| marci@478 |    369 | 	queue.pop();
 | 
| marci@478 |    370 | 
 | 
| marci@478 |    371 | 	InEdgeIt e;
 | 
| marci@478 |    372 | 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
 | 
| marci@478 |    373 | 	  Node v=g->tail(e);
 | 
| marci@478 |    374 | 	  if (M[v] && (*flow)[e] < (*capacity)[e] ) {
 | 
| marci@478 |    375 | 	    queue.push(v);
 | 
| marci@478 |    376 | 	    M.set(v, false);
 | 
| marci@478 |    377 | 	  }
 | 
| marci@478 |    378 | 	}
 | 
| marci@615 |    379 | 
 | 
| marci@478 |    380 | 	OutEdgeIt f;
 | 
| marci@478 |    381 | 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
 | 
| marci@478 |    382 | 	  Node v=g->head(f);
 | 
| marci@478 |    383 | 	  if (M[v] && (*flow)[f] > 0 ) {
 | 
| marci@478 |    384 | 	    queue.push(v);
 | 
| marci@478 |    385 | 	    M.set(v, false);
 | 
| marci@478 |    386 | 	  }
 | 
| marci@478 |    387 | 	}
 | 
| marci@478 |    388 |       }
 | 
| marci@478 |    389 |     }
 | 
| marci@478 |    390 | 
 | 
| jacint@631 |    391 |     ///Returns a minimum value cut.
 | 
| marci@478 |    392 | 
 | 
| jacint@631 |    393 |     ///Sets \c M to the characteristic vector of a minimum value cut.
 | 
| jacint@631 |    394 |     ///\pre M should be a node map of bools initialized to false.
 | 
| jacint@631 |    395 |     ///\pre \c flow must be a maximum flow.    
 | 
| marci@478 |    396 |     template<typename CutMap>
 | 
| marci@647 |    397 |     void minCut(CutMap& M) const { minMinCut(M); }
 | 
| marci@478 |    398 | 
 | 
| jacint@631 |    399 |     ///Resets the source node to \c _s.
 | 
| jacint@631 |    400 | 
 | 
| jacint@631 |    401 |     ///Resets the source node to \c _s.
 | 
| jacint@631 |    402 |     /// 
 | 
| marci@647 |    403 |     void resetSource(Node _s) { s=_s; status=AFTER_NOTHING; }
 | 
| jacint@631 |    404 | 
 | 
| jacint@631 |    405 |     ///Resets the target node to \c _t.
 | 
| jacint@631 |    406 | 
 | 
| jacint@631 |    407 |     ///Resets the target node to \c _t.
 | 
| marci@487 |    408 |     ///
 | 
| marci@647 |    409 |     void resetTarget(Node _t) { t=_t; status=AFTER_NOTHING; }
 | 
| marci@615 |    410 | 
 | 
| jacint@631 |    411 |     /// Resets the edge map of the capacities to _cap.
 | 
| jacint@631 |    412 | 
 | 
| jacint@631 |    413 |     /// Resets the edge map of the capacities to _cap.
 | 
| jacint@631 |    414 |     /// 
 | 
| marci@647 |    415 |     void resetCap(const CapMap& _cap) { capacity=&_cap; status=AFTER_NOTHING; }
 | 
| marci@615 |    416 | 
 | 
| jacint@631 |    417 |     /// Resets the edge map of the flows to _flow.
 | 
| jacint@631 |    418 | 
 | 
| jacint@631 |    419 |     /// Resets the edge map of the flows to _flow.
 | 
| jacint@631 |    420 |     /// 
 | 
| marci@647 |    421 |     void resetFlow(FlowMap& _flow) { flow=&_flow; status=AFTER_NOTHING; }
 | 
| marci@478 |    422 | 
 | 
| marci@478 |    423 | 
 | 
| marci@478 |    424 |   private:
 | 
| marci@478 |    425 | 
 | 
| marci@478 |    426 |     int push(Node w, VecStack& active) {
 | 
| marci@615 |    427 | 
 | 
| marci@478 |    428 |       int lev=level[w];
 | 
| marci@478 |    429 |       Num exc=excess[w];
 | 
| marci@478 |    430 |       int newlevel=n;       //bound on the next level of w
 | 
| marci@615 |    431 | 
 | 
| marci@478 |    432 |       OutEdgeIt e;
 | 
| marci@478 |    433 |       for(g->first(e,w); g->valid(e); g->next(e)) {
 | 
| marci@615 |    434 | 
 | 
| marci@615 |    435 | 	if ( (*flow)[e] >= (*capacity)[e] ) continue;
 | 
| marci@615 |    436 | 	Node v=g->head(e);
 | 
| marci@615 |    437 | 
 | 
| marci@478 |    438 | 	if( lev > level[v] ) { //Push is allowed now
 | 
| marci@615 |    439 | 
 | 
| marci@478 |    440 | 	  if ( excess[v]<=0 && v!=t && v!=s ) {
 | 
| marci@478 |    441 | 	    int lev_v=level[v];
 | 
| marci@478 |    442 | 	    active[lev_v].push(v);
 | 
| marci@478 |    443 | 	  }
 | 
| marci@615 |    444 | 
 | 
| marci@478 |    445 | 	  Num cap=(*capacity)[e];
 | 
| marci@478 |    446 | 	  Num flo=(*flow)[e];
 | 
| marci@478 |    447 | 	  Num remcap=cap-flo;
 | 
| marci@615 |    448 | 
 | 
| marci@478 |    449 | 	  if ( remcap >= exc ) { //A nonsaturating push.
 | 
| marci@615 |    450 | 
 | 
| marci@478 |    451 | 	    flow->set(e, flo+exc);
 | 
| marci@478 |    452 | 	    excess.set(v, excess[v]+exc);
 | 
| marci@478 |    453 | 	    exc=0;
 | 
| marci@615 |    454 | 	    break;
 | 
| marci@615 |    455 | 
 | 
| marci@478 |    456 | 	  } else { //A saturating push.
 | 
| marci@478 |    457 | 	    flow->set(e, cap);
 | 
| marci@478 |    458 | 	    excess.set(v, excess[v]+remcap);
 | 
| marci@478 |    459 | 	    exc-=remcap;
 | 
| marci@478 |    460 | 	  }
 | 
| marci@478 |    461 | 	} else if ( newlevel > level[v] ) newlevel = level[v];
 | 
| marci@615 |    462 |       } //for out edges wv
 | 
| marci@615 |    463 | 
 | 
| marci@615 |    464 |       if ( exc > 0 ) {
 | 
| marci@478 |    465 | 	InEdgeIt e;
 | 
| marci@478 |    466 | 	for(g->first(e,w); g->valid(e); g->next(e)) {
 | 
| marci@615 |    467 | 
 | 
| marci@615 |    468 | 	  if( (*flow)[e] <= 0 ) continue;
 | 
| marci@615 |    469 | 	  Node v=g->tail(e);
 | 
| marci@615 |    470 | 
 | 
| marci@478 |    471 | 	  if( lev > level[v] ) { //Push is allowed now
 | 
| marci@615 |    472 | 
 | 
| marci@478 |    473 | 	    if ( excess[v]<=0 && v!=t && v!=s ) {
 | 
| marci@478 |    474 | 	      int lev_v=level[v];
 | 
| marci@478 |    475 | 	      active[lev_v].push(v);
 | 
| marci@478 |    476 | 	    }
 | 
| marci@615 |    477 | 
 | 
| marci@478 |    478 | 	    Num flo=(*flow)[e];
 | 
| marci@615 |    479 | 
 | 
| marci@478 |    480 | 	    if ( flo >= exc ) { //A nonsaturating push.
 | 
| marci@615 |    481 | 
 | 
| marci@478 |    482 | 	      flow->set(e, flo-exc);
 | 
| marci@478 |    483 | 	      excess.set(v, excess[v]+exc);
 | 
| marci@478 |    484 | 	      exc=0;
 | 
| marci@615 |    485 | 	      break;
 | 
| marci@478 |    486 | 	    } else {  //A saturating push.
 | 
| marci@615 |    487 | 
 | 
| marci@478 |    488 | 	      excess.set(v, excess[v]+flo);
 | 
| marci@478 |    489 | 	      exc-=flo;
 | 
| marci@478 |    490 | 	      flow->set(e,0);
 | 
| marci@615 |    491 | 	    }
 | 
| marci@478 |    492 | 	  } else if ( newlevel > level[v] ) newlevel = level[v];
 | 
| marci@478 |    493 | 	} //for in edges vw
 | 
| marci@615 |    494 | 
 | 
| marci@478 |    495 |       } // if w still has excess after the out edge for cycle
 | 
| marci@615 |    496 | 
 | 
| marci@478 |    497 |       excess.set(w, exc);
 | 
| marci@615 |    498 | 
 | 
| marci@478 |    499 |       return newlevel;
 | 
| marci@485 |    500 |     }
 | 
| marci@478 |    501 | 
 | 
| marci@478 |    502 | 
 | 
| marci@647 |    503 |     void preflowPreproc(FlowEnum fe, VecStack& active,
 | 
| marci@615 |    504 | 			VecNode& level_list, NNMap& left, NNMap& right)
 | 
| marci@602 |    505 |     {
 | 
| marci@615 |    506 |       std::queue<Node> bfs_queue;
 | 
| marci@478 |    507 | 
 | 
| marci@615 |    508 |       switch (fe) {
 | 
| jacint@631 |    509 |       case NO_FLOW:   //flow is already set to const zero in this case
 | 
| marci@615 |    510 |       case ZERO_FLOW:
 | 
| marci@602 |    511 | 	{
 | 
| marci@602 |    512 | 	  //Reverse_bfs from t, to find the starting level.
 | 
| marci@602 |    513 | 	  level.set(t,0);
 | 
| marci@602 |    514 | 	  bfs_queue.push(t);
 | 
| marci@615 |    515 | 
 | 
| marci@602 |    516 | 	  while (!bfs_queue.empty()) {
 | 
| marci@615 |    517 | 
 | 
| marci@615 |    518 | 	    Node v=bfs_queue.front();
 | 
| marci@602 |    519 | 	    bfs_queue.pop();
 | 
| marci@602 |    520 | 	    int l=level[v]+1;
 | 
| marci@615 |    521 | 
 | 
| marci@602 |    522 | 	    InEdgeIt e;
 | 
| marci@602 |    523 | 	    for(g->first(e,v); g->valid(e); g->next(e)) {
 | 
| marci@602 |    524 | 	      Node w=g->tail(e);
 | 
| marci@602 |    525 | 	      if ( level[w] == n && w != s ) {
 | 
| marci@602 |    526 | 		bfs_queue.push(w);
 | 
| marci@602 |    527 | 		Node first=level_list[l];
 | 
| marci@602 |    528 | 		if ( g->valid(first) ) left.set(first,w);
 | 
| marci@602 |    529 | 		right.set(w,first);
 | 
| marci@602 |    530 | 		level_list[l]=w;
 | 
| marci@602 |    531 | 		level.set(w, l);
 | 
| marci@602 |    532 | 	      }
 | 
| marci@602 |    533 | 	    }
 | 
| marci@602 |    534 | 	  }
 | 
| marci@615 |    535 | 
 | 
| marci@602 |    536 | 	  //the starting flow
 | 
| marci@602 |    537 | 	  OutEdgeIt e;
 | 
| marci@615 |    538 | 	  for(g->first(e,s); g->valid(e); g->next(e))
 | 
| marci@602 |    539 | 	    {
 | 
| marci@602 |    540 | 	      Num c=(*capacity)[e];
 | 
| marci@602 |    541 | 	      if ( c <= 0 ) continue;
 | 
| marci@602 |    542 | 	      Node w=g->head(e);
 | 
| marci@615 |    543 | 	      if ( level[w] < n ) {
 | 
| marci@602 |    544 | 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
 | 
| marci@615 |    545 | 		flow->set(e, c);
 | 
| marci@602 |    546 | 		excess.set(w, excess[w]+c);
 | 
| marci@602 |    547 | 	      }
 | 
| marci@602 |    548 | 	    }
 | 
| marci@602 |    549 | 	  break;
 | 
| marci@602 |    550 | 	}
 | 
| marci@615 |    551 | 
 | 
| marci@602 |    552 |       case GEN_FLOW:
 | 
| marci@615 |    553 |       case PRE_FLOW:
 | 
| marci@602 |    554 | 	{
 | 
| marci@615 |    555 | 	  //Reverse_bfs from t in the residual graph,
 | 
| marci@602 |    556 | 	  //to find the starting level.
 | 
| marci@602 |    557 | 	  level.set(t,0);
 | 
| marci@602 |    558 | 	  bfs_queue.push(t);
 | 
| marci@615 |    559 | 
 | 
| marci@602 |    560 | 	  while (!bfs_queue.empty()) {
 | 
| marci@615 |    561 | 
 | 
| marci@615 |    562 | 	    Node v=bfs_queue.front();
 | 
| marci@602 |    563 | 	    bfs_queue.pop();
 | 
| marci@602 |    564 | 	    int l=level[v]+1;
 | 
| marci@615 |    565 | 
 | 
| marci@602 |    566 | 	    InEdgeIt e;
 | 
| marci@602 |    567 | 	    for(g->first(e,v); g->valid(e); g->next(e)) {
 | 
| marci@602 |    568 | 	      if ( (*capacity)[e] <= (*flow)[e] ) continue;
 | 
| marci@602 |    569 | 	      Node w=g->tail(e);
 | 
| marci@602 |    570 | 	      if ( level[w] == n && w != s ) {
 | 
| marci@602 |    571 | 		bfs_queue.push(w);
 | 
| marci@602 |    572 | 		Node first=level_list[l];
 | 
| marci@602 |    573 | 		if ( g->valid(first) ) left.set(first,w);
 | 
| marci@602 |    574 | 		right.set(w,first);
 | 
| marci@602 |    575 | 		level_list[l]=w;
 | 
| marci@602 |    576 | 		level.set(w, l);
 | 
| marci@602 |    577 | 	      }
 | 
| marci@602 |    578 | 	    }
 | 
| marci@615 |    579 | 
 | 
| marci@602 |    580 | 	    OutEdgeIt f;
 | 
| marci@602 |    581 | 	    for(g->first(f,v); g->valid(f); g->next(f)) {
 | 
| marci@602 |    582 | 	      if ( 0 >= (*flow)[f] ) continue;
 | 
| marci@602 |    583 | 	      Node w=g->head(f);
 | 
| marci@602 |    584 | 	      if ( level[w] == n && w != s ) {
 | 
| marci@602 |    585 | 		bfs_queue.push(w);
 | 
| marci@602 |    586 | 		Node first=level_list[l];
 | 
| marci@602 |    587 | 		if ( g->valid(first) ) left.set(first,w);
 | 
| marci@602 |    588 | 		right.set(w,first);
 | 
| marci@602 |    589 | 		level_list[l]=w;
 | 
| marci@602 |    590 | 		level.set(w, l);
 | 
| marci@602 |    591 | 	      }
 | 
| marci@602 |    592 | 	    }
 | 
| marci@602 |    593 | 	  }
 | 
| marci@615 |    594 | 
 | 
| marci@615 |    595 | 
 | 
| marci@602 |    596 | 	  //the starting flow
 | 
| marci@602 |    597 | 	  OutEdgeIt e;
 | 
| marci@615 |    598 | 	  for(g->first(e,s); g->valid(e); g->next(e))
 | 
| marci@602 |    599 | 	    {
 | 
| marci@602 |    600 | 	      Num rem=(*capacity)[e]-(*flow)[e];
 | 
| marci@602 |    601 | 	      if ( rem <= 0 ) continue;
 | 
| marci@602 |    602 | 	      Node w=g->head(e);
 | 
| marci@615 |    603 | 	      if ( level[w] < n ) {
 | 
| marci@602 |    604 | 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
 | 
| marci@615 |    605 | 		flow->set(e, (*capacity)[e]);
 | 
| marci@602 |    606 | 		excess.set(w, excess[w]+rem);
 | 
| marci@602 |    607 | 	      }
 | 
| marci@602 |    608 | 	    }
 | 
| marci@615 |    609 | 
 | 
| marci@602 |    610 | 	  InEdgeIt f;
 | 
| marci@615 |    611 | 	  for(g->first(f,s); g->valid(f); g->next(f))
 | 
| marci@602 |    612 | 	    {
 | 
| marci@602 |    613 | 	      if ( (*flow)[f] <= 0 ) continue;
 | 
| marci@602 |    614 | 	      Node w=g->tail(f);
 | 
| marci@615 |    615 | 	      if ( level[w] < n ) {
 | 
| marci@602 |    616 | 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
 | 
| marci@602 |    617 | 		excess.set(w, excess[w]+(*flow)[f]);
 | 
| marci@615 |    618 | 		flow->set(f, 0);
 | 
| marci@602 |    619 | 	      }
 | 
| marci@615 |    620 | 	    }
 | 
| marci@602 |    621 | 	  break;
 | 
| marci@615 |    622 | 	} //case PRE_FLOW
 | 
| marci@602 |    623 |       }
 | 
| marci@602 |    624 |     } //preflowPreproc
 | 
| marci@478 |    625 | 
 | 
| marci@478 |    626 | 
 | 
| marci@478 |    627 | 
 | 
| marci@615 |    628 |     void relabel(Node w, int newlevel, VecStack& active,
 | 
| marci@615 |    629 | 		 VecNode& level_list, NNMap& left,
 | 
| marci@615 |    630 | 		 NNMap& right, int& b, int& k, bool what_heur )
 | 
| marci@478 |    631 |     {
 | 
| marci@478 |    632 | 
 | 
| marci@615 |    633 |       Num lev=level[w];
 | 
| marci@615 |    634 | 
 | 
| marci@478 |    635 |       Node right_n=right[w];
 | 
| marci@478 |    636 |       Node left_n=left[w];
 | 
| marci@615 |    637 | 
 | 
| marci@478 |    638 |       //unlacing starts
 | 
| marci@478 |    639 |       if ( g->valid(right_n) ) {
 | 
| marci@478 |    640 | 	if ( g->valid(left_n) ) {
 | 
| marci@478 |    641 | 	  right.set(left_n, right_n);
 | 
| marci@478 |    642 | 	  left.set(right_n, left_n);
 | 
| marci@478 |    643 | 	} else {
 | 
| marci@615 |    644 | 	  level_list[lev]=right_n;
 | 
| marci@478 |    645 | 	  left.set(right_n, INVALID);
 | 
| marci@615 |    646 | 	}
 | 
| marci@478 |    647 |       } else {
 | 
| marci@478 |    648 | 	if ( g->valid(left_n) ) {
 | 
| marci@478 |    649 | 	  right.set(left_n, INVALID);
 | 
| marci@615 |    650 | 	} else {
 | 
| marci@615 |    651 | 	  level_list[lev]=INVALID;
 | 
| marci@615 |    652 | 	}
 | 
| marci@615 |    653 |       }
 | 
| marci@478 |    654 |       //unlacing ends
 | 
| marci@615 |    655 | 
 | 
| marci@478 |    656 |       if ( !g->valid(level_list[lev]) ) {
 | 
| marci@615 |    657 | 
 | 
| marci@478 |    658 | 	//gapping starts
 | 
| marci@478 |    659 | 	for (int i=lev; i!=k ; ) {
 | 
| marci@478 |    660 | 	  Node v=level_list[++i];
 | 
| marci@478 |    661 | 	  while ( g->valid(v) ) {
 | 
| marci@478 |    662 | 	    level.set(v,n);
 | 
| marci@478 |    663 | 	    v=right[v];
 | 
| marci@478 |    664 | 	  }
 | 
| marci@478 |    665 | 	  level_list[i]=INVALID;
 | 
| marci@478 |    666 | 	  if ( !what_heur ) {
 | 
| marci@478 |    667 | 	    while ( !active[i].empty() ) {
 | 
| marci@478 |    668 | 	      active[i].pop();    //FIXME: ezt szebben kene
 | 
| marci@478 |    669 | 	    }
 | 
| marci@615 |    670 | 	  }
 | 
| marci@478 |    671 | 	}
 | 
| marci@615 |    672 | 
 | 
| marci@478 |    673 | 	level.set(w,n);
 | 
| marci@478 |    674 | 	b=lev-1;
 | 
| marci@478 |    675 | 	k=b;
 | 
| marci@478 |    676 | 	//gapping ends
 | 
| marci@615 |    677 | 
 | 
| marci@478 |    678 |       } else {
 | 
| marci@615 |    679 | 
 | 
| marci@615 |    680 | 	if ( newlevel == n ) level.set(w,n);
 | 
| marci@478 |    681 | 	else {
 | 
| marci@478 |    682 | 	  level.set(w,++newlevel);
 | 
| marci@478 |    683 | 	  active[newlevel].push(w);
 | 
| marci@478 |    684 | 	  if ( what_heur ) b=newlevel;
 | 
| marci@478 |    685 | 	  if ( k < newlevel ) ++k;      //now k=newlevel
 | 
| marci@478 |    686 | 	  Node first=level_list[newlevel];
 | 
| marci@478 |    687 | 	  if ( g->valid(first) ) left.set(first,w);
 | 
| marci@478 |    688 | 	  right.set(w,first);
 | 
| marci@478 |    689 | 	  left.set(w,INVALID);
 | 
| marci@478 |    690 | 	  level_list[newlevel]=w;
 | 
| marci@478 |    691 | 	}
 | 
| marci@478 |    692 |       }
 | 
| marci@615 |    693 | 
 | 
| marci@478 |    694 |     } //relabel
 | 
| marci@478 |    695 | 
 | 
| marci@478 |    696 | 
 | 
| marci@615 |    697 |     template<typename MapGraphWrapper>
 | 
| marci@478 |    698 |     class DistanceMap {
 | 
| marci@478 |    699 |     protected:
 | 
| marci@478 |    700 |       const MapGraphWrapper* g;
 | 
| marci@615 |    701 |       typename MapGraphWrapper::template NodeMap<int> dist;
 | 
| marci@478 |    702 |     public:
 | 
| marci@478 |    703 |       DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
 | 
| marci@615 |    704 |       void set(const typename MapGraphWrapper::Node& n, int a) {
 | 
| marci@615 |    705 | 	dist.set(n, a);
 | 
| marci@478 |    706 |       }
 | 
| marci@647 |    707 |       int operator[](const typename MapGraphWrapper::Node& n) const { 
 | 
| marci@647 |    708 | 	return dist[n]; 
 | 
| marci@647 |    709 |       }
 | 
| marci@615 |    710 |       //       int get(const typename MapGraphWrapper::Node& n) const {
 | 
| marci@485 |    711 |       // 	return dist[n]; }
 | 
| marci@615 |    712 |       //       bool get(const typename MapGraphWrapper::Edge& e) const {
 | 
| marci@485 |    713 |       // 	return (dist.get(g->tail(e))<dist.get(g->head(e))); }
 | 
| marci@615 |    714 |       bool operator[](const typename MapGraphWrapper::Edge& e) const {
 | 
| marci@615 |    715 | 	return (dist[g->tail(e)]<dist[g->head(e)]);
 | 
| marci@478 |    716 |       }
 | 
| marci@478 |    717 |     };
 | 
| marci@615 |    718 | 
 | 
| marci@478 |    719 |   };
 | 
| marci@478 |    720 | 
 | 
| marci@478 |    721 | 
 | 
| marci@478 |    722 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| marci@647 |    723 |   void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1(FlowEnum fe)
 | 
| marci@478 |    724 |   {
 | 
| marci@615 |    725 | 
 | 
| marci@615 |    726 |     int heur0=(int)(H0*n);  //time while running 'bound decrease'
 | 
| marci@485 |    727 |     int heur1=(int)(H1*n);  //time while running 'highest label'
 | 
| marci@485 |    728 |     int heur=heur1;         //starting time interval (#of relabels)
 | 
| marci@485 |    729 |     int numrelabel=0;
 | 
| marci@615 |    730 | 
 | 
| marci@615 |    731 |     bool what_heur=1;
 | 
| marci@485 |    732 |     //It is 0 in case 'bound decrease' and 1 in case 'highest label'
 | 
| marci@478 |    733 | 
 | 
| marci@615 |    734 |     bool end=false;
 | 
| marci@615 |    735 |     //Needed for 'bound decrease', true means no active nodes are above bound
 | 
| marci@615 |    736 |     //b.
 | 
| marci@478 |    737 | 
 | 
| marci@485 |    738 |     int k=n-2;  //bound on the highest level under n containing a node
 | 
| marci@485 |    739 |     int b=k;    //bound on the highest level under n of an active node
 | 
| marci@615 |    740 | 
 | 
| marci@485 |    741 |     VecStack active(n);
 | 
| marci@615 |    742 | 
 | 
| marci@485 |    743 |     NNMap left(*g, INVALID);
 | 
| marci@485 |    744 |     NNMap right(*g, INVALID);
 | 
| marci@485 |    745 |     VecNode level_list(n,INVALID);
 | 
| marci@485 |    746 |     //List of the nodes in level i<n, set to n.
 | 
| marci@478 |    747 | 
 | 
| marci@485 |    748 |     NodeIt v;
 | 
| marci@485 |    749 |     for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
 | 
| marci@485 |    750 |     //setting each node to level n
 | 
| marci@615 |    751 | 
 | 
| jacint@631 |    752 |     if ( fe == NO_FLOW ) {
 | 
| jacint@631 |    753 |       EdgeIt e;
 | 
| jacint@631 |    754 |       for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
 | 
| jacint@631 |    755 |     }
 | 
| jacint@631 |    756 | 
 | 
| jacint@631 |    757 |     switch (fe) { //computing the excess
 | 
| marci@615 |    758 |     case PRE_FLOW:
 | 
| marci@485 |    759 |       {
 | 
| marci@485 |    760 | 	NodeIt v;
 | 
| marci@485 |    761 | 	for(g->first(v); g->valid(v); g->next(v)) {
 | 
| marci@478 |    762 | 	  Num exc=0;
 | 
| marci@615 |    763 | 
 | 
| marci@478 |    764 | 	  InEdgeIt e;
 | 
| marci@485 |    765 | 	  for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
 | 
| marci@478 |    766 | 	  OutEdgeIt f;
 | 
| marci@485 |    767 | 	  for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
 | 
| marci@615 |    768 | 
 | 
| marci@615 |    769 | 	  excess.set(v,exc);
 | 
| marci@615 |    770 | 
 | 
| marci@485 |    771 | 	  //putting the active nodes into the stack
 | 
| marci@485 |    772 | 	  int lev=level[v];
 | 
| marci@485 |    773 | 	  if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
 | 
| marci@478 |    774 | 	}
 | 
| marci@478 |    775 | 	break;
 | 
| marci@478 |    776 |       }
 | 
| marci@485 |    777 |     case GEN_FLOW:
 | 
| marci@485 |    778 |       {
 | 
| jacint@631 |    779 | 	NodeIt v;
 | 
| jacint@631 |    780 | 	for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
 | 
| jacint@631 |    781 | 
 | 
| marci@485 |    782 | 	Num exc=0;
 | 
| marci@485 |    783 | 	InEdgeIt e;
 | 
| marci@485 |    784 | 	for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
 | 
| marci@485 |    785 | 	OutEdgeIt f;
 | 
| marci@485 |    786 | 	for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
 | 
| marci@615 |    787 | 	excess.set(t,exc);
 | 
| marci@485 |    788 | 	break;
 | 
| marci@485 |    789 |       }
 | 
| jacint@631 |    790 |     case ZERO_FLOW:
 | 
| jacint@631 |    791 |     case NO_FLOW:
 | 
| jacint@631 |    792 |       {
 | 
| jacint@631 |    793 | 	NodeIt v;
 | 
| jacint@631 |    794 |         for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
 | 
| jacint@631 |    795 | 	break;
 | 
| jacint@631 |    796 |       }
 | 
| marci@485 |    797 |     }
 | 
| marci@615 |    798 | 
 | 
| marci@615 |    799 |     preflowPreproc(fe, active, level_list, left, right);
 | 
| marci@615 |    800 |     //End of preprocessing
 | 
| marci@615 |    801 | 
 | 
| marci@615 |    802 | 
 | 
| marci@485 |    803 |     //Push/relabel on the highest level active nodes.
 | 
| marci@485 |    804 |     while ( true ) {
 | 
| marci@485 |    805 |       if ( b == 0 ) {
 | 
| marci@485 |    806 | 	if ( !what_heur && !end && k > 0 ) {
 | 
| marci@485 |    807 | 	  b=k;
 | 
| marci@485 |    808 | 	  end=true;
 | 
| marci@485 |    809 | 	} else break;
 | 
| marci@485 |    810 |       }
 | 
| marci@615 |    811 | 
 | 
| marci@615 |    812 |       if ( active[b].empty() ) --b;
 | 
| marci@485 |    813 |       else {
 | 
| marci@615 |    814 | 	end=false;
 | 
| marci@485 |    815 | 	Node w=active[b].top();
 | 
| marci@485 |    816 | 	active[b].pop();
 | 
| marci@485 |    817 | 	int newlevel=push(w,active);
 | 
| marci@615 |    818 | 	if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
 | 
| marci@485 |    819 | 				     left, right, b, k, what_heur);
 | 
| marci@615 |    820 | 
 | 
| marci@615 |    821 | 	++numrelabel;
 | 
| marci@485 |    822 | 	if ( numrelabel >= heur ) {
 | 
| marci@485 |    823 | 	  numrelabel=0;
 | 
| marci@485 |    824 | 	  if ( what_heur ) {
 | 
| marci@485 |    825 | 	    what_heur=0;
 | 
| marci@485 |    826 | 	    heur=heur0;
 | 
| marci@485 |    827 | 	    end=false;
 | 
| marci@485 |    828 | 	  } else {
 | 
| marci@485 |    829 | 	    what_heur=1;
 | 
| marci@485 |    830 | 	    heur=heur1;
 | 
| marci@615 |    831 | 	    b=k;
 | 
| marci@485 |    832 | 	  }
 | 
| marci@478 |    833 | 	}
 | 
| marci@615 |    834 |       }
 | 
| marci@615 |    835 |     }
 | 
| marci@647 |    836 | 
 | 
| marci@647 |    837 |     status=AFTER_PRE_FLOW_PHASE_1;
 | 
| marci@485 |    838 |   }
 | 
| marci@478 |    839 | 
 | 
| marci@478 |    840 | 
 | 
| marci@478 |    841 | 
 | 
| marci@478 |    842 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| jacint@631 |    843 |   void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase2()
 | 
| marci@478 |    844 |   {
 | 
| marci@615 |    845 | 
 | 
| marci@485 |    846 |     int k=n-2;  //bound on the highest level under n containing a node
 | 
| marci@485 |    847 |     int b=k;    //bound on the highest level under n of an active node
 | 
| marci@615 |    848 | 
 | 
| marci@485 |    849 |     VecStack active(n);
 | 
| marci@485 |    850 |     level.set(s,0);
 | 
| marci@485 |    851 |     std::queue<Node> bfs_queue;
 | 
| marci@485 |    852 |     bfs_queue.push(s);
 | 
| marci@615 |    853 | 
 | 
| marci@485 |    854 |     while (!bfs_queue.empty()) {
 | 
| marci@615 |    855 | 
 | 
| marci@615 |    856 |       Node v=bfs_queue.front();
 | 
| marci@485 |    857 |       bfs_queue.pop();
 | 
| marci@485 |    858 |       int l=level[v]+1;
 | 
| marci@615 |    859 | 
 | 
| marci@485 |    860 |       InEdgeIt e;
 | 
| marci@485 |    861 |       for(g->first(e,v); g->valid(e); g->next(e)) {
 | 
| marci@485 |    862 | 	if ( (*capacity)[e] <= (*flow)[e] ) continue;
 | 
| marci@485 |    863 | 	Node u=g->tail(e);
 | 
| marci@615 |    864 | 	if ( level[u] >= n ) {
 | 
| marci@485 |    865 | 	  bfs_queue.push(u);
 | 
| marci@485 |    866 | 	  level.set(u, l);
 | 
| marci@485 |    867 | 	  if ( excess[u] > 0 ) active[l].push(u);
 | 
| marci@478 |    868 | 	}
 | 
| marci@478 |    869 |       }
 | 
| marci@615 |    870 | 
 | 
| marci@485 |    871 |       OutEdgeIt f;
 | 
| marci@485 |    872 |       for(g->first(f,v); g->valid(f); g->next(f)) {
 | 
| marci@485 |    873 | 	if ( 0 >= (*flow)[f] ) continue;
 | 
| marci@485 |    874 | 	Node u=g->head(f);
 | 
| marci@615 |    875 | 	if ( level[u] >= n ) {
 | 
| marci@485 |    876 | 	  bfs_queue.push(u);
 | 
| marci@485 |    877 | 	  level.set(u, l);
 | 
| marci@485 |    878 | 	  if ( excess[u] > 0 ) active[l].push(u);
 | 
| marci@485 |    879 | 	}
 | 
| marci@485 |    880 |       }
 | 
| marci@485 |    881 |     }
 | 
| marci@485 |    882 |     b=n-2;
 | 
| marci@478 |    883 | 
 | 
| marci@485 |    884 |     while ( true ) {
 | 
| marci@615 |    885 | 
 | 
| marci@485 |    886 |       if ( b == 0 ) break;
 | 
| marci@478 |    887 | 
 | 
| marci@615 |    888 |       if ( active[b].empty() ) --b;
 | 
| marci@485 |    889 |       else {
 | 
| marci@485 |    890 | 	Node w=active[b].top();
 | 
| marci@485 |    891 | 	active[b].pop();
 | 
| marci@615 |    892 | 	int newlevel=push(w,active);
 | 
| marci@478 |    893 | 
 | 
| marci@485 |    894 | 	//relabel
 | 
| marci@485 |    895 | 	if ( excess[w] > 0 ) {
 | 
| marci@485 |    896 | 	  level.set(w,++newlevel);
 | 
| marci@485 |    897 | 	  active[newlevel].push(w);
 | 
| marci@485 |    898 | 	  b=newlevel;
 | 
| marci@485 |    899 | 	}
 | 
| marci@485 |    900 |       }  // if stack[b] is nonempty
 | 
| marci@485 |    901 |     } // while(true)
 | 
| marci@647 |    902 | 
 | 
| marci@647 |    903 |     status=AFTER_PRE_FLOW_PHASE_2;
 | 
| marci@485 |    904 |   }
 | 
| marci@478 |    905 | 
 | 
| marci@478 |    906 | 
 | 
| marci@478 |    907 | 
 | 
| marci@478 |    908 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| marci@615 |    909 |   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
 | 
| marci@478 |    910 |   {
 | 
| marci@485 |    911 |     ResGW res_graph(*g, *capacity, *flow);
 | 
| marci@485 |    912 |     bool _augment=false;
 | 
| marci@615 |    913 | 
 | 
| marci@485 |    914 |     //ReachedMap level(res_graph);
 | 
| marci@485 |    915 |     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
 | 
| marci@485 |    916 |     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
 | 
| marci@485 |    917 |     bfs.pushAndSetReached(s);
 | 
| marci@615 |    918 | 
 | 
| marci@615 |    919 |     typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
 | 
| marci@485 |    920 |     pred.set(s, INVALID);
 | 
| marci@615 |    921 | 
 | 
| marci@485 |    922 |     typename ResGW::template NodeMap<Num> free(res_graph);
 | 
| marci@615 |    923 | 
 | 
| marci@485 |    924 |     //searching for augmenting path
 | 
| marci@615 |    925 |     while ( !bfs.finished() ) {
 | 
| marci@485 |    926 |       ResGWOutEdgeIt e=bfs;
 | 
| marci@485 |    927 |       if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@485 |    928 | 	Node v=res_graph.tail(e);
 | 
| marci@485 |    929 | 	Node w=res_graph.head(e);
 | 
| marci@485 |    930 | 	pred.set(w, e);
 | 
| marci@485 |    931 | 	if (res_graph.valid(pred[v])) {
 | 
| marci@485 |    932 | 	  free.set(w, std::min(free[v], res_graph.resCap(e)));
 | 
| marci@485 |    933 | 	} else {
 | 
| marci@615 |    934 | 	  free.set(w, res_graph.resCap(e));
 | 
| marci@478 |    935 | 	}
 | 
| marci@485 |    936 | 	if (res_graph.head(e)==t) { _augment=true; break; }
 | 
| marci@485 |    937 |       }
 | 
| marci@615 |    938 | 
 | 
| marci@485 |    939 |       ++bfs;
 | 
| marci@485 |    940 |     } //end of searching augmenting path
 | 
| marci@478 |    941 | 
 | 
| marci@485 |    942 |     if (_augment) {
 | 
| marci@485 |    943 |       Node n=t;
 | 
| marci@485 |    944 |       Num augment_value=free[t];
 | 
| marci@615 |    945 |       while (res_graph.valid(pred[n])) {
 | 
| marci@485 |    946 | 	ResGWEdge e=pred[n];
 | 
| marci@615 |    947 | 	res_graph.augment(e, augment_value);
 | 
| marci@485 |    948 | 	n=res_graph.tail(e);
 | 
| marci@478 |    949 |       }
 | 
| marci@485 |    950 |     }
 | 
| marci@478 |    951 | 
 | 
| marci@647 |    952 |     status=AFTER_AUGMENTING;
 | 
| marci@485 |    953 |     return _augment;
 | 
| marci@485 |    954 |   }
 | 
| marci@478 |    955 | 
 | 
| marci@478 |    956 | 
 | 
| marci@647 |    957 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| marci@647 |    958 |   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath2()
 | 
| marci@647 |    959 |   {
 | 
| marci@647 |    960 |     ResGW res_graph(*g, *capacity, *flow);
 | 
| marci@647 |    961 |     bool _augment=false;
 | 
| marci@478 |    962 | 
 | 
| marci@656 |    963 |     if (status!=AFTER_FAST_AUGMENTING) {
 | 
| marci@656 |    964 |       FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0); 
 | 
| marci@656 |    965 |       number_of_augmentations=1;
 | 
| marci@647 |    966 |     } else {
 | 
| marci@647 |    967 |       ++number_of_augmentations;
 | 
| marci@647 |    968 |     }
 | 
| marci@647 |    969 |     TrickyReachedMap<ReachedMap> 
 | 
| marci@647 |    970 |       tricky_reached_map(level, number_of_augmentations);
 | 
| marci@647 |    971 |     //ReachedMap level(res_graph);
 | 
| marci@647 |    972 | //    FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
 | 
| marci@647 |    973 |     BfsIterator<ResGW, TrickyReachedMap<ReachedMap> > 
 | 
| marci@647 |    974 |       bfs(res_graph, tricky_reached_map);
 | 
| marci@647 |    975 |     bfs.pushAndSetReached(s);
 | 
| marci@478 |    976 | 
 | 
| marci@647 |    977 |     typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
 | 
| marci@647 |    978 |     pred.set(s, INVALID);
 | 
| marci@478 |    979 | 
 | 
| marci@647 |    980 |     typename ResGW::template NodeMap<Num> free(res_graph);
 | 
| marci@647 |    981 | 
 | 
| marci@647 |    982 |     //searching for augmenting path
 | 
| marci@647 |    983 |     while ( !bfs.finished() ) {
 | 
| marci@647 |    984 |       ResGWOutEdgeIt e=bfs;
 | 
| marci@647 |    985 |       if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@647 |    986 | 	Node v=res_graph.tail(e);
 | 
| marci@647 |    987 | 	Node w=res_graph.head(e);
 | 
| marci@647 |    988 | 	pred.set(w, e);
 | 
| marci@647 |    989 | 	if (res_graph.valid(pred[v])) {
 | 
| marci@647 |    990 | 	  free.set(w, std::min(free[v], res_graph.resCap(e)));
 | 
| marci@647 |    991 | 	} else {
 | 
| marci@647 |    992 | 	  free.set(w, res_graph.resCap(e));
 | 
| marci@647 |    993 | 	}
 | 
| marci@647 |    994 | 	if (res_graph.head(e)==t) { _augment=true; break; }
 | 
| marci@647 |    995 |       }
 | 
| marci@647 |    996 | 
 | 
| marci@647 |    997 |       ++bfs;
 | 
| marci@647 |    998 |     } //end of searching augmenting path
 | 
| marci@647 |    999 | 
 | 
| marci@647 |   1000 |     if (_augment) {
 | 
| marci@647 |   1001 |       Node n=t;
 | 
| marci@647 |   1002 |       Num augment_value=free[t];
 | 
| marci@647 |   1003 |       while (res_graph.valid(pred[n])) {
 | 
| marci@647 |   1004 | 	ResGWEdge e=pred[n];
 | 
| marci@647 |   1005 | 	res_graph.augment(e, augment_value);
 | 
| marci@647 |   1006 | 	n=res_graph.tail(e);
 | 
| marci@647 |   1007 |       }
 | 
| marci@647 |   1008 |     }
 | 
| marci@647 |   1009 | 
 | 
| marci@656 |   1010 |     status=AFTER_FAST_AUGMENTING;
 | 
| marci@647 |   1011 |     return _augment;
 | 
| marci@647 |   1012 |   }
 | 
| marci@478 |   1013 | 
 | 
| marci@478 |   1014 | 
 | 
| marci@478 |   1015 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| marci@615 |   1016 |   template<typename MutableGraph>
 | 
| marci@615 |   1017 |   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
 | 
| marci@615 |   1018 |   {
 | 
| marci@485 |   1019 |     typedef MutableGraph MG;
 | 
| marci@485 |   1020 |     bool _augment=false;
 | 
| marci@478 |   1021 | 
 | 
| marci@485 |   1022 |     ResGW res_graph(*g, *capacity, *flow);
 | 
| marci@478 |   1023 | 
 | 
| marci@485 |   1024 |     //bfs for distances on the residual graph
 | 
| marci@485 |   1025 |     //ReachedMap level(res_graph);
 | 
| marci@485 |   1026 |     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
 | 
| marci@485 |   1027 |     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
 | 
| marci@485 |   1028 |     bfs.pushAndSetReached(s);
 | 
| marci@615 |   1029 |     typename ResGW::template NodeMap<int>
 | 
| marci@485 |   1030 |       dist(res_graph); //filled up with 0's
 | 
| marci@478 |   1031 | 
 | 
| marci@485 |   1032 |     //F will contain the physical copy of the residual graph
 | 
| marci@485 |   1033 |     //with the set of edges which are on shortest paths
 | 
| marci@485 |   1034 |     MG F;
 | 
| marci@615 |   1035 |     typename ResGW::template NodeMap<typename MG::Node>
 | 
| marci@485 |   1036 |       res_graph_to_F(res_graph);
 | 
| marci@485 |   1037 |     {
 | 
| marci@485 |   1038 |       typename ResGW::NodeIt n;
 | 
| marci@485 |   1039 |       for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
 | 
| marci@485 |   1040 | 	res_graph_to_F.set(n, F.addNode());
 | 
| marci@478 |   1041 |       }
 | 
| marci@485 |   1042 |     }
 | 
| marci@478 |   1043 | 
 | 
| marci@485 |   1044 |     typename MG::Node sF=res_graph_to_F[s];
 | 
| marci@485 |   1045 |     typename MG::Node tF=res_graph_to_F[t];
 | 
| marci@485 |   1046 |     typename MG::template EdgeMap<ResGWEdge> original_edge(F);
 | 
| marci@485 |   1047 |     typename MG::template EdgeMap<Num> residual_capacity(F);
 | 
| marci@478 |   1048 | 
 | 
| marci@615 |   1049 |     while ( !bfs.finished() ) {
 | 
| marci@485 |   1050 |       ResGWOutEdgeIt e=bfs;
 | 
| marci@485 |   1051 |       if (res_graph.valid(e)) {
 | 
| marci@485 |   1052 | 	if (bfs.isBNodeNewlyReached()) {
 | 
| marci@485 |   1053 | 	  dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
 | 
| marci@615 |   1054 | 	  typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)],
 | 
| marci@615 |   1055 | 					res_graph_to_F[res_graph.head(e)]);
 | 
| marci@485 |   1056 | 	  original_edge.update();
 | 
| marci@485 |   1057 | 	  original_edge.set(f, e);
 | 
| marci@485 |   1058 | 	  residual_capacity.update();
 | 
| marci@485 |   1059 | 	  residual_capacity.set(f, res_graph.resCap(e));
 | 
| marci@485 |   1060 | 	} else {
 | 
| marci@485 |   1061 | 	  if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
 | 
| marci@615 |   1062 | 	    typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)],
 | 
| marci@615 |   1063 | 					  res_graph_to_F[res_graph.head(e)]);
 | 
| marci@478 |   1064 | 	    original_edge.update();
 | 
| marci@478 |   1065 | 	    original_edge.set(f, e);
 | 
| marci@478 |   1066 | 	    residual_capacity.update();
 | 
| marci@478 |   1067 | 	    residual_capacity.set(f, res_graph.resCap(e));
 | 
| marci@478 |   1068 | 	  }
 | 
| marci@478 |   1069 | 	}
 | 
| marci@485 |   1070 |       }
 | 
| marci@485 |   1071 |       ++bfs;
 | 
| marci@485 |   1072 |     } //computing distances from s in the residual graph
 | 
| marci@478 |   1073 | 
 | 
| marci@485 |   1074 |     bool __augment=true;
 | 
| marci@478 |   1075 | 
 | 
| marci@485 |   1076 |     while (__augment) {
 | 
| marci@485 |   1077 |       __augment=false;
 | 
| marci@485 |   1078 |       //computing blocking flow with dfs
 | 
| marci@485 |   1079 |       DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
 | 
| marci@485 |   1080 |       typename MG::template NodeMap<typename MG::Edge> pred(F);
 | 
| marci@485 |   1081 |       pred.set(sF, INVALID);
 | 
| marci@485 |   1082 |       //invalid iterators for sources
 | 
| marci@478 |   1083 | 
 | 
| marci@485 |   1084 |       typename MG::template NodeMap<Num> free(F);
 | 
| marci@478 |   1085 | 
 | 
| marci@615 |   1086 |       dfs.pushAndSetReached(sF);
 | 
| marci@485 |   1087 |       while (!dfs.finished()) {
 | 
| marci@485 |   1088 | 	++dfs;
 | 
| marci@485 |   1089 | 	if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
 | 
| marci@485 |   1090 | 	  if (dfs.isBNodeNewlyReached()) {
 | 
| marci@485 |   1091 | 	    typename MG::Node v=F.aNode(dfs);
 | 
| marci@485 |   1092 | 	    typename MG::Node w=F.bNode(dfs);
 | 
| marci@485 |   1093 | 	    pred.set(w, dfs);
 | 
| marci@485 |   1094 | 	    if (F.valid(pred[v])) {
 | 
| marci@485 |   1095 | 	      free.set(w, std::min(free[v], residual_capacity[dfs]));
 | 
| marci@485 |   1096 | 	    } else {
 | 
| marci@615 |   1097 | 	      free.set(w, residual_capacity[dfs]);
 | 
| marci@485 |   1098 | 	    }
 | 
| marci@615 |   1099 | 	    if (w==tF) {
 | 
| marci@615 |   1100 | 	      __augment=true;
 | 
| marci@485 |   1101 | 	      _augment=true;
 | 
| marci@615 |   1102 | 	      break;
 | 
| marci@485 |   1103 | 	    }
 | 
| marci@615 |   1104 | 
 | 
| marci@485 |   1105 | 	  } else {
 | 
| marci@485 |   1106 | 	    F.erase(/*typename MG::OutEdgeIt*/(dfs));
 | 
| marci@485 |   1107 | 	  }
 | 
| marci@615 |   1108 | 	}
 | 
| marci@485 |   1109 |       }
 | 
| marci@485 |   1110 | 
 | 
| marci@485 |   1111 |       if (__augment) {
 | 
| marci@485 |   1112 | 	typename MG::Node n=tF;
 | 
| marci@485 |   1113 | 	Num augment_value=free[tF];
 | 
| marci@615 |   1114 | 	while (F.valid(pred[n])) {
 | 
| marci@485 |   1115 | 	  typename MG::Edge e=pred[n];
 | 
| marci@615 |   1116 | 	  res_graph.augment(original_edge[e], augment_value);
 | 
| marci@485 |   1117 | 	  n=F.tail(e);
 | 
| marci@615 |   1118 | 	  if (residual_capacity[e]==augment_value)
 | 
| marci@615 |   1119 | 	    F.erase(e);
 | 
| marci@615 |   1120 | 	  else
 | 
| marci@485 |   1121 | 	    residual_capacity.set(e, residual_capacity[e]-augment_value);
 | 
| marci@478 |   1122 | 	}
 | 
| marci@485 |   1123 |       }
 | 
| marci@615 |   1124 | 
 | 
| marci@485 |   1125 |     }
 | 
| marci@615 |   1126 | 
 | 
| marci@647 |   1127 |     status=AFTER_AUGMENTING;
 | 
| marci@485 |   1128 |     return _augment;
 | 
| marci@485 |   1129 |   }
 | 
| marci@478 |   1130 | 
 | 
| marci@478 |   1131 | 
 | 
| marci@478 |   1132 | 
 | 
| marci@478 |   1133 | 
 | 
| marci@478 |   1134 |   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
 | 
| marci@615 |   1135 |   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
 | 
| marci@478 |   1136 |   {
 | 
| marci@485 |   1137 |     bool _augment=false;
 | 
| marci@478 |   1138 | 
 | 
| marci@485 |   1139 |     ResGW res_graph(*g, *capacity, *flow);
 | 
| marci@615 |   1140 | 
 | 
| marci@485 |   1141 |     //ReachedMap level(res_graph);
 | 
| marci@485 |   1142 |     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
 | 
| marci@485 |   1143 |     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
 | 
| marci@478 |   1144 | 
 | 
| marci@485 |   1145 |     bfs.pushAndSetReached(s);
 | 
| marci@485 |   1146 |     DistanceMap<ResGW> dist(res_graph);
 | 
| marci@615 |   1147 |     while ( !bfs.finished() ) {
 | 
| marci@485 |   1148 |       ResGWOutEdgeIt e=bfs;
 | 
| marci@485 |   1149 |       if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@485 |   1150 | 	dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
 | 
| marci@485 |   1151 |       }
 | 
| marci@485 |   1152 |       ++bfs;
 | 
| marci@485 |   1153 |     } //computing distances from s in the residual graph
 | 
| marci@478 |   1154 | 
 | 
| marci@478 |   1155 |       //Subgraph containing the edges on some shortest paths
 | 
| marci@485 |   1156 |     ConstMap<typename ResGW::Node, bool> true_map(true);
 | 
| marci@615 |   1157 |     typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
 | 
| marci@485 |   1158 |       DistanceMap<ResGW> > FilterResGW;
 | 
| marci@485 |   1159 |     FilterResGW filter_res_graph(res_graph, true_map, dist);
 | 
| marci@478 |   1160 | 
 | 
| marci@615 |   1161 |     //Subgraph, which is able to delete edges which are already
 | 
| marci@485 |   1162 |     //met by the dfs
 | 
| marci@615 |   1163 |     typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
 | 
| marci@485 |   1164 |       first_out_edges(filter_res_graph);
 | 
| marci@485 |   1165 |     typename FilterResGW::NodeIt v;
 | 
| marci@615 |   1166 |     for(filter_res_graph.first(v); filter_res_graph.valid(v);
 | 
| marci@615 |   1167 | 	filter_res_graph.next(v))
 | 
| marci@478 |   1168 |       {
 | 
| marci@478 |   1169 |  	typename FilterResGW::OutEdgeIt e;
 | 
| marci@478 |   1170 |  	filter_res_graph.first(e, v);
 | 
| marci@478 |   1171 |  	first_out_edges.set(v, e);
 | 
| marci@478 |   1172 |       }
 | 
| marci@485 |   1173 |     typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
 | 
| marci@485 |   1174 |       template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
 | 
| marci@485 |   1175 |     ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
 | 
| marci@478 |   1176 | 
 | 
| marci@485 |   1177 |     bool __augment=true;
 | 
| marci@478 |   1178 | 
 | 
| marci@485 |   1179 |     while (__augment) {
 | 
| marci@478 |   1180 | 
 | 
| marci@485 |   1181 |       __augment=false;
 | 
| marci@485 |   1182 |       //computing blocking flow with dfs
 | 
| marci@615 |   1183 |       DfsIterator< ErasingResGW,
 | 
| marci@615 |   1184 | 	typename ErasingResGW::template NodeMap<bool> >
 | 
| marci@485 |   1185 | 	dfs(erasing_res_graph);
 | 
| marci@485 |   1186 |       typename ErasingResGW::
 | 
| marci@615 |   1187 | 	template NodeMap<typename ErasingResGW::OutEdgeIt>
 | 
| marci@615 |   1188 | 	pred(erasing_res_graph);
 | 
| marci@485 |   1189 |       pred.set(s, INVALID);
 | 
| marci@485 |   1190 |       //invalid iterators for sources
 | 
| marci@478 |   1191 | 
 | 
| marci@615 |   1192 |       typename ErasingResGW::template NodeMap<Num>
 | 
| marci@485 |   1193 | 	free1(erasing_res_graph);
 | 
| marci@478 |   1194 | 
 | 
| marci@615 |   1195 |       dfs.pushAndSetReached
 | 
| alpar@921 |   1196 | 	///\bug lemon 0.2
 | 
| marci@615 |   1197 | 	(typename ErasingResGW::Node
 | 
| marci@615 |   1198 | 	 (typename FilterResGW::Node
 | 
| marci@615 |   1199 | 	  (typename ResGW::Node(s)
 | 
| marci@615 |   1200 | 	   )
 | 
| marci@615 |   1201 | 	  )
 | 
| marci@615 |   1202 | 	 );
 | 
| marci@485 |   1203 |       while (!dfs.finished()) {
 | 
| marci@485 |   1204 | 	++dfs;
 | 
| marci@615 |   1205 | 	if (erasing_res_graph.valid(typename ErasingResGW::OutEdgeIt(dfs)))
 | 
| marci@615 |   1206 |  	  {
 | 
| marci@478 |   1207 |   	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@615 |   1208 | 
 | 
| marci@478 |   1209 |  	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
 | 
| marci@478 |   1210 |  	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
 | 
| marci@478 |   1211 | 
 | 
| marci@478 |   1212 |  	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
 | 
| marci@478 |   1213 |  	      if (erasing_res_graph.valid(pred[v])) {
 | 
| marci@615 |   1214 |  		free1.set
 | 
| marci@615 |   1215 | 		  (w, std::min(free1[v], res_graph.resCap
 | 
| marci@615 |   1216 | 			       (typename ErasingResGW::OutEdgeIt(dfs))));
 | 
| marci@478 |   1217 |  	      } else {
 | 
| marci@615 |   1218 |  		free1.set
 | 
| marci@615 |   1219 | 		  (w, res_graph.resCap
 | 
| marci@615 |   1220 | 		   (typename ErasingResGW::OutEdgeIt(dfs)));
 | 
| marci@478 |   1221 |  	      }
 | 
| marci@615 |   1222 | 
 | 
| marci@615 |   1223 |  	      if (w==t) {
 | 
| marci@615 |   1224 |  		__augment=true;
 | 
| marci@478 |   1225 |  		_augment=true;
 | 
| marci@615 |   1226 |  		break;
 | 
| marci@478 |   1227 |  	      }
 | 
| marci@478 |   1228 |  	    } else {
 | 
| marci@478 |   1229 |  	      erasing_res_graph.erase(dfs);
 | 
| marci@478 |   1230 | 	    }
 | 
| marci@478 |   1231 | 	  }
 | 
| marci@615 |   1232 |       }
 | 
| marci@478 |   1233 | 
 | 
| marci@485 |   1234 |       if (__augment) {
 | 
| marci@615 |   1235 | 	typename ErasingResGW::Node
 | 
| marci@615 |   1236 | 	  n=typename FilterResGW::Node(typename ResGW::Node(t));
 | 
| marci@485 |   1237 | 	// 	  typename ResGW::NodeMap<Num> a(res_graph);
 | 
| marci@485 |   1238 | 	// 	  typename ResGW::Node b;
 | 
| marci@485 |   1239 | 	// 	  Num j=a[b];
 | 
| marci@485 |   1240 | 	// 	  typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
 | 
| marci@485 |   1241 | 	// 	  typename FilterResGW::Node b1;
 | 
| marci@485 |   1242 | 	// 	  Num j1=a1[b1];
 | 
| marci@485 |   1243 | 	// 	  typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
 | 
| marci@485 |   1244 | 	// 	  typename ErasingResGW::Node b2;
 | 
| marci@485 |   1245 | 	// 	  Num j2=a2[b2];
 | 
| marci@485 |   1246 | 	Num augment_value=free1[n];
 | 
| marci@615 |   1247 | 	while (erasing_res_graph.valid(pred[n])) {
 | 
| marci@485 |   1248 | 	  typename ErasingResGW::OutEdgeIt e=pred[n];
 | 
| marci@485 |   1249 | 	  res_graph.augment(e, augment_value);
 | 
| marci@485 |   1250 | 	  n=erasing_res_graph.tail(e);
 | 
| marci@485 |   1251 | 	  if (res_graph.resCap(e)==0)
 | 
| marci@485 |   1252 | 	    erasing_res_graph.erase(e);
 | 
| marci@478 |   1253 | 	}
 | 
| marci@478 |   1254 |       }
 | 
| marci@615 |   1255 | 
 | 
| marci@615 |   1256 |     } //while (__augment)
 | 
| marci@615 |   1257 | 
 | 
| marci@647 |   1258 |     status=AFTER_AUGMENTING;
 | 
| marci@485 |   1259 |     return _augment;
 | 
| marci@485 |   1260 |   }
 | 
| marci@478 |   1261 | 
 | 
| marci@478 |   1262 | 
 | 
| alpar@921 |   1263 | } //namespace lemon
 | 
| marci@478 |   1264 | 
 | 
| alpar@921 |   1265 | #endif //LEMON_MAX_FLOW_H
 | 
| marci@478 |   1266 | 
 | 
| marci@478 |   1267 | 
 | 
| marci@478 |   1268 | 
 | 
| marci@478 |   1269 | 
 |