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