| marci@281 |      1 | // -*- c++ -*-
 | 
| marci@281 |      2 | #ifndef HUGO_EDMONDS_KARP_H
 | 
| marci@281 |      3 | #define HUGO_EDMONDS_KARP_H
 | 
| marci@281 |      4 | 
 | 
| marci@281 |      5 | #include <algorithm>
 | 
| marci@281 |      6 | #include <list>
 | 
| marci@281 |      7 | #include <iterator>
 | 
| marci@281 |      8 | 
 | 
| marci@281 |      9 | #include <bfs_iterator_1.h>
 | 
| marci@281 |     10 | #include <invalid.h>
 | 
| marci@281 |     11 | #include <graph_wrapper_1.h>
 | 
| marci@281 |     12 | 
 | 
| marci@281 |     13 | namespace hugo {
 | 
| marci@281 |     14 | 
 | 
| marci@281 |     15 |   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
 | 
| marci@281 |     16 |   class ResGraph {
 | 
| marci@281 |     17 |   public:
 | 
| marci@281 |     18 |     typedef typename Graph::Node Node;
 | 
| marci@281 |     19 |     typedef typename Graph::NodeIt NodeIt;
 | 
| marci@281 |     20 |   private:
 | 
| marci@281 |     21 |     typedef typename Graph::SymEdgeIt OldSymEdgeIt;
 | 
| marci@281 |     22 |     const Graph& G;
 | 
| marci@281 |     23 |     FlowMap& flow;
 | 
| marci@281 |     24 |     const CapacityMap& capacity;
 | 
| marci@281 |     25 |   public:
 | 
| marci@281 |     26 |     ResGraph(const Graph& _G, FlowMap& _flow, 
 | 
| marci@281 |     27 | 	     const CapacityMap& _capacity) : 
 | 
| marci@281 |     28 |       G(_G), flow(_flow), capacity(_capacity) { }
 | 
| marci@281 |     29 | 
 | 
| marci@281 |     30 |     class Edge; 
 | 
| marci@281 |     31 |     class OutEdgeIt; 
 | 
| marci@281 |     32 |     friend class Edge; 
 | 
| marci@281 |     33 |     friend class OutEdgeIt; 
 | 
| marci@281 |     34 | 
 | 
| marci@281 |     35 |     class Edge {
 | 
| marci@281 |     36 |       friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
 | 
| marci@281 |     37 |     protected:
 | 
| marci@281 |     38 |       const ResGraph<Graph, Number, FlowMap, CapacityMap>* resG;
 | 
| marci@281 |     39 |       OldSymEdgeIt sym;
 | 
| marci@281 |     40 |     public:
 | 
| marci@281 |     41 |       Edge() { } 
 | 
| marci@281 |     42 |       //Edge(const Edge& e) : resG(e.resG), sym(e.sym) { }
 | 
| marci@281 |     43 |       Number free() const { 
 | 
| marci@281 |     44 | 	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
 | 
| marci@281 |     45 | 	  return (resG->capacity.get(sym)-resG->flow.get(sym)); 
 | 
| marci@281 |     46 | 	} else { 
 | 
| marci@281 |     47 | 	  return (resG->flow.get(sym)); 
 | 
| marci@281 |     48 | 	}
 | 
| marci@281 |     49 |       }
 | 
| marci@281 |     50 |       bool valid() const { return sym.valid(); }
 | 
| marci@281 |     51 |       void augment(Number a) const {
 | 
| marci@281 |     52 | 	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
 | 
| marci@281 |     53 | 	  resG->flow.set(sym, resG->flow.get(sym)+a);
 | 
| marci@281 |     54 | 	  //resG->flow[sym]+=a;
 | 
| marci@281 |     55 | 	} else { 
 | 
| marci@281 |     56 | 	  resG->flow.set(sym, resG->flow.get(sym)-a);
 | 
| marci@281 |     57 | 	  //resG->flow[sym]-=a;
 | 
| marci@281 |     58 | 	}
 | 
| marci@281 |     59 |       }
 | 
| marci@281 |     60 |     };
 | 
| marci@281 |     61 | 
 | 
| marci@281 |     62 |     class OutEdgeIt : public Edge {
 | 
| marci@281 |     63 |       friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
 | 
| marci@281 |     64 |     public:
 | 
| marci@281 |     65 |       OutEdgeIt() { }
 | 
| marci@281 |     66 |       //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
 | 
| marci@281 |     67 |     private:
 | 
| marci@281 |     68 |       OutEdgeIt(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
 | 
| marci@281 |     69 |       	resG=&_resG;
 | 
| marci@281 |     70 | 	sym=resG->G.template first<OldSymEdgeIt>(v);
 | 
| marci@281 |     71 | 	while( sym.valid() && !(free()>0) ) { ++sym; }
 | 
| marci@281 |     72 |       }
 | 
| marci@281 |     73 |     public:
 | 
| marci@281 |     74 |       OutEdgeIt& operator++() { 
 | 
| marci@281 |     75 | 	++sym; 
 | 
| marci@281 |     76 | 	while( sym.valid() && !(free()>0) ) { ++sym; }
 | 
| marci@281 |     77 | 	return *this; 
 | 
| marci@281 |     78 |       }
 | 
| marci@281 |     79 |     };
 | 
| marci@281 |     80 | 
 | 
| marci@281 |     81 |     void /*getF*/first(OutEdgeIt& e, Node v) const { 
 | 
| marci@281 |     82 |       e=OutEdgeIt(*this, v); 
 | 
| marci@281 |     83 |     }
 | 
| marci@281 |     84 |     void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
 | 
| marci@281 |     85 |     
 | 
| marci@281 |     86 |     template< typename It >
 | 
| marci@281 |     87 |     It first() const { 
 | 
| marci@281 |     88 |       It e;      
 | 
| marci@281 |     89 |       /*getF*/first(e);
 | 
| marci@281 |     90 |       return e; 
 | 
| marci@281 |     91 |     }
 | 
| marci@281 |     92 | 
 | 
| marci@281 |     93 |     template< typename It >
 | 
| marci@281 |     94 |     It first(Node v) const { 
 | 
| marci@281 |     95 |       It e;
 | 
| marci@281 |     96 |       /*getF*/first(e, v);
 | 
| marci@281 |     97 |       return e; 
 | 
| marci@281 |     98 |     }
 | 
| marci@281 |     99 | 
 | 
| marci@281 |    100 |     Node tail(Edge e) const { return G.aNode(e.sym); }
 | 
| marci@281 |    101 |     Node head(Edge e) const { return G.bNode(e.sym); }
 | 
| marci@281 |    102 | 
 | 
| marci@281 |    103 |     Node aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
 | 
| marci@281 |    104 |     Node bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
 | 
| marci@281 |    105 | 
 | 
| marci@281 |    106 |     int id(Node v) const { return G.id(v); }
 | 
| marci@281 |    107 | 
 | 
| marci@281 |    108 |     template <typename S>
 | 
| marci@281 |    109 |     class NodeMap {
 | 
| marci@281 |    110 |       typename Graph::NodeMap<S> node_map; 
 | 
| marci@281 |    111 |     public:
 | 
| marci@281 |    112 |       NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
 | 
| marci@281 |    113 |       NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
 | 
| marci@281 |    114 |       void set(Node nit, S a) { node_map.set(nit, a); }
 | 
| marci@281 |    115 |       S get(Node nit) const { return node_map.get(nit); }
 | 
| marci@281 |    116 |       S& operator[](Node nit) { return node_map[nit]; } 
 | 
| marci@281 |    117 |       const S& operator[](Node nit) const { return node_map[nit]; } 
 | 
| marci@281 |    118 |     };
 | 
| marci@281 |    119 | 
 | 
| marci@281 |    120 |   };
 | 
| marci@281 |    121 | 
 | 
| marci@281 |    122 | 
 | 
| marci@281 |    123 |   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
 | 
| marci@281 |    124 |   class ResGraph2 {
 | 
| marci@281 |    125 |   public:
 | 
| marci@281 |    126 |     typedef typename Graph::Node Node;
 | 
| marci@281 |    127 |     typedef typename Graph::NodeIt NodeIt;
 | 
| marci@281 |    128 |   private:
 | 
| marci@281 |    129 |     //typedef typename Graph::SymEdgeIt OldSymEdgeIt;
 | 
| marci@281 |    130 |     typedef typename Graph::OutEdgeIt OldOutEdgeIt;
 | 
| marci@281 |    131 |     typedef typename Graph::InEdgeIt OldInEdgeIt;
 | 
| marci@281 |    132 |     
 | 
| marci@281 |    133 |     const Graph& G;
 | 
| marci@281 |    134 |     FlowMap& flow;
 | 
| marci@281 |    135 |     const CapacityMap& capacity;
 | 
| marci@281 |    136 |   public:
 | 
| marci@281 |    137 |     ResGraph2(const Graph& _G, FlowMap& _flow, 
 | 
| marci@281 |    138 | 	     const CapacityMap& _capacity) : 
 | 
| marci@281 |    139 |       G(_G), flow(_flow), capacity(_capacity) { }
 | 
| marci@281 |    140 | 
 | 
| marci@281 |    141 |     class Edge; 
 | 
| marci@281 |    142 |     class OutEdgeIt; 
 | 
| marci@281 |    143 |     friend class Edge; 
 | 
| marci@281 |    144 |     friend class OutEdgeIt; 
 | 
| marci@281 |    145 | 
 | 
| marci@281 |    146 |     class Edge {
 | 
| marci@281 |    147 |       friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
 | 
| marci@281 |    148 |     protected:
 | 
| marci@281 |    149 |       const ResGraph2<Graph, Number, FlowMap, CapacityMap>* resG;
 | 
| marci@281 |    150 |       //OldSymEdgeIt sym;
 | 
| marci@281 |    151 |       OldOutEdgeIt out;
 | 
| marci@281 |    152 |       OldInEdgeIt in;
 | 
| marci@281 |    153 |       bool out_or_in; //true, iff out
 | 
| marci@281 |    154 |     public:
 | 
| marci@281 |    155 |       Edge() : out_or_in(true) { } 
 | 
| marci@281 |    156 |       Number free() const { 
 | 
| marci@281 |    157 | 	if (out_or_in) { 
 | 
| marci@281 |    158 | 	  return (resG->capacity.get(out)-resG->flow.get(out)); 
 | 
| marci@281 |    159 | 	} else { 
 | 
| marci@281 |    160 | 	  return (resG->flow.get(in)); 
 | 
| marci@281 |    161 | 	}
 | 
| marci@281 |    162 |       }
 | 
| marci@281 |    163 |       bool valid() const { 
 | 
| marci@281 |    164 | 	return out_or_in && out.valid() || in.valid(); }
 | 
| marci@281 |    165 |       void augment(Number a) const {
 | 
| marci@281 |    166 | 	if (out_or_in) { 
 | 
| marci@281 |    167 | 	  resG->flow.set(out, resG->flow.get(out)+a);
 | 
| marci@281 |    168 | 	} else { 
 | 
| marci@281 |    169 | 	  resG->flow.set(in, resG->flow.get(in)-a);
 | 
| marci@281 |    170 | 	}
 | 
| marci@281 |    171 |       }
 | 
| marci@281 |    172 |     };
 | 
| marci@281 |    173 | 
 | 
| marci@281 |    174 |     class OutEdgeIt : public Edge {
 | 
| marci@281 |    175 |       friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
 | 
| marci@281 |    176 |     public:
 | 
| marci@281 |    177 |       OutEdgeIt() { }
 | 
| marci@281 |    178 |     private:
 | 
| marci@281 |    179 |       OutEdgeIt(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
 | 
| marci@281 |    180 |       	resG=&_resG;
 | 
| marci@281 |    181 | 	out=resG->G.template first<OldOutEdgeIt>(v);
 | 
| marci@281 |    182 | 	while( out.valid() && !(free()>0) ) { ++out; }
 | 
| marci@281 |    183 | 	if (!out.valid()) {
 | 
| marci@281 |    184 | 	  out_or_in=0;
 | 
| marci@281 |    185 | 	  in=resG->G.template first<OldInEdgeIt>(v);
 | 
| marci@281 |    186 | 	  while( in.valid() && !(free()>0) ) { ++in; }
 | 
| marci@281 |    187 | 	}
 | 
| marci@281 |    188 |       }
 | 
| marci@281 |    189 |     public:
 | 
| marci@281 |    190 |       OutEdgeIt& operator++() { 
 | 
| marci@281 |    191 | 	if (out_or_in) {
 | 
| marci@281 |    192 | 	  Node v=resG->G.aNode(out);
 | 
| marci@281 |    193 | 	  ++out;
 | 
| marci@281 |    194 | 	  while( out.valid() && !(free()>0) ) { ++out; }
 | 
| marci@281 |    195 | 	  if (!out.valid()) {
 | 
| marci@281 |    196 | 	    out_or_in=0;
 | 
| marci@281 |    197 | 	    in=resG->G.template first<OldInEdgeIt>(v);
 | 
| marci@281 |    198 | 	    while( in.valid() && !(free()>0) ) { ++in; }
 | 
| marci@281 |    199 | 	  }
 | 
| marci@281 |    200 | 	} else {
 | 
| marci@281 |    201 | 	  ++in;
 | 
| marci@281 |    202 | 	  while( in.valid() && !(free()>0) ) { ++in; } 
 | 
| marci@281 |    203 | 	}
 | 
| marci@281 |    204 | 	return *this; 
 | 
| marci@281 |    205 |       }
 | 
| marci@281 |    206 |     };
 | 
| marci@281 |    207 | 
 | 
| marci@281 |    208 |     void /*getF*/first(OutEdgeIt& e, Node v) const { 
 | 
| marci@281 |    209 |       e=OutEdgeIt(*this, v); 
 | 
| marci@281 |    210 |     }
 | 
| marci@281 |    211 |     void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
 | 
| marci@281 |    212 |     
 | 
| marci@281 |    213 |     template< typename It >
 | 
| marci@281 |    214 |     It first() const { 
 | 
| marci@281 |    215 |       It e;
 | 
| marci@281 |    216 |       /*getF*/first(e);
 | 
| marci@281 |    217 |       return e; 
 | 
| marci@281 |    218 |     }
 | 
| marci@281 |    219 | 
 | 
| marci@281 |    220 |     template< typename It >
 | 
| marci@281 |    221 |     It first(Node v) const { 
 | 
| marci@281 |    222 |       It e;
 | 
| marci@281 |    223 |       /*getF*/first(e, v);
 | 
| marci@281 |    224 |       return e; 
 | 
| marci@281 |    225 |     }
 | 
| marci@281 |    226 | 
 | 
| marci@281 |    227 |     Node tail(Edge e) const { 
 | 
| marci@281 |    228 |       return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
 | 
| marci@281 |    229 |     Node head(Edge e) const { 
 | 
| marci@281 |    230 |       return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
 | 
| marci@281 |    231 | 
 | 
| marci@281 |    232 |     Node aNode(OutEdgeIt e) const { 
 | 
| marci@281 |    233 |       return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
 | 
| marci@281 |    234 |     Node bNode(OutEdgeIt e) const { 
 | 
| marci@281 |    235 |       return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
 | 
| marci@281 |    236 | 
 | 
| marci@281 |    237 |     int id(Node v) const { return G.id(v); }
 | 
| marci@281 |    238 | 
 | 
| marci@281 |    239 |     template <typename S>
 | 
| marci@281 |    240 |     class NodeMap {
 | 
| marci@281 |    241 |       typename Graph::NodeMap<S> node_map; 
 | 
| marci@281 |    242 |     public:
 | 
| marci@281 |    243 |       NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
 | 
| marci@281 |    244 |       NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
 | 
| marci@281 |    245 |       void set(Node nit, S a) { node_map.set(nit, a); }
 | 
| marci@281 |    246 |       S get(Node nit) const { return node_map.get(nit); }
 | 
| marci@281 |    247 |     };
 | 
| marci@281 |    248 |   };
 | 
| marci@281 |    249 | 
 | 
| marci@281 |    250 | 
 | 
| marci@298 |    251 |   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
 | 
| marci@281 |    252 |   class MaxFlow {
 | 
| marci@281 |    253 |   protected:
 | 
| marci@298 |    254 |     typedef typename Graph::Node Node;
 | 
| marci@298 |    255 |     typedef typename Graph::Edge Edge;
 | 
| marci@298 |    256 |     typedef typename Graph::EdgeIt EdgeIt;
 | 
| marci@298 |    257 |     typedef typename Graph::OutEdgeIt OutEdgeIt;
 | 
| marci@298 |    258 |     typedef typename Graph::InEdgeIt InEdgeIt;
 | 
| marci@298 |    259 |     const Graph* g;
 | 
| marci@281 |    260 |     Node s;
 | 
| marci@281 |    261 |     Node t;
 | 
| marci@281 |    262 |     FlowMap* flow;
 | 
| marci@281 |    263 |     const CapacityMap* capacity;
 | 
| marci@298 |    264 |     typedef ResGraphWrapper<const Graph, Number, FlowMap, CapacityMap > ResGW;
 | 
| marci@281 |    265 |     typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
 | 
| marci@281 |    266 |     typedef typename ResGW::Edge ResGWEdge;
 | 
| marci@281 |    267 |   public:
 | 
| marci@281 |    268 | 
 | 
| marci@298 |    269 |     MaxFlow(const Graph& _g, Node _s, Node _t, FlowMap& _flow, const CapacityMap& _capacity) : 
 | 
| marci@281 |    270 |       g(&_g), s(_s), t(_t), flow(&_flow), capacity(&_capacity) { }
 | 
| marci@281 |    271 | 
 | 
| marci@281 |    272 |     bool augmentOnShortestPath() {
 | 
| marci@281 |    273 |       ResGW res_graph(*g, *flow, *capacity);
 | 
| marci@281 |    274 |       bool _augment=false;
 | 
| marci@281 |    275 |       
 | 
| marci@281 |    276 |       typedef typename ResGW::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    277 |       BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
 | 
| marci@281 |    278 |       bfs.pushAndSetReached(s);
 | 
| marci@281 |    279 | 	
 | 
| marci@281 |    280 |       typename ResGW::NodeMap<ResGWEdge> pred(res_graph); 
 | 
| marci@281 |    281 |       pred.set(s, INVALID);
 | 
| marci@281 |    282 |       
 | 
| marci@281 |    283 |       typename ResGW::NodeMap<Number> free(res_graph);
 | 
| marci@281 |    284 | 	
 | 
| marci@281 |    285 |       //searching for augmenting path
 | 
| marci@281 |    286 |       while ( !bfs.finished() ) { 
 | 
| marci@281 |    287 | 	ResGWOutEdgeIt e=bfs;
 | 
| marci@281 |    288 | 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    289 | 	  Node v=res_graph.tail(e);
 | 
| marci@281 |    290 | 	  Node w=res_graph.head(e);
 | 
| marci@281 |    291 | 	  pred.set(w, e);
 | 
| marci@281 |    292 | 	  if (res_graph.valid(pred.get(v))) {
 | 
| marci@281 |    293 | 	    free.set(w, std::min(free.get(v), res_graph.resCap(e)));
 | 
| marci@281 |    294 | 	  } else {
 | 
| marci@281 |    295 | 	    free.set(w, res_graph.resCap(e)); 
 | 
| marci@281 |    296 | 	  }
 | 
| marci@281 |    297 | 	  if (res_graph.head(e)==t) { _augment=true; break; }
 | 
| marci@281 |    298 | 	}
 | 
| marci@281 |    299 | 	
 | 
| marci@281 |    300 | 	++bfs;
 | 
| marci@281 |    301 |       } //end of searching augmenting path
 | 
| marci@281 |    302 | 
 | 
| marci@281 |    303 |       if (_augment) {
 | 
| marci@281 |    304 | 	Node n=t;
 | 
| marci@281 |    305 | 	Number augment_value=free.get(t);
 | 
| marci@281 |    306 | 	while (res_graph.valid(pred.get(n))) { 
 | 
| marci@281 |    307 | 	  ResGWEdge e=pred.get(n);
 | 
| marci@281 |    308 | 	  res_graph.augment(e, augment_value); 
 | 
| marci@281 |    309 | 	  n=res_graph.tail(e);
 | 
| marci@281 |    310 | 	}
 | 
| marci@281 |    311 |       }
 | 
| marci@281 |    312 | 
 | 
| marci@281 |    313 |       return _augment;
 | 
| marci@281 |    314 |     }
 | 
| marci@281 |    315 | 
 | 
| marci@281 |    316 |     template<typename MapGraphWrapper> 
 | 
| marci@281 |    317 |     class DistanceMap {
 | 
| marci@281 |    318 |     protected:
 | 
| marci@281 |    319 |       const MapGraphWrapper* g;
 | 
| marci@281 |    320 |       typename MapGraphWrapper::NodeMap<int> dist; 
 | 
| marci@281 |    321 |     public:
 | 
| marci@281 |    322 |       DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
 | 
| marci@281 |    323 |       void set(const typename MapGraphWrapper::Node& n, int a) { dist[n]=a; }
 | 
| marci@281 |    324 |       int get(const typename MapGraphWrapper::Node& n) const { return dist[n]; }
 | 
| marci@281 |    325 |       bool get(const typename MapGraphWrapper::Edge& e) const { 
 | 
| marci@281 |    326 | 	return (dist.get(g->tail(e))<dist.get(g->head(e))); 
 | 
| marci@281 |    327 |       }
 | 
| marci@281 |    328 |     };
 | 
| marci@281 |    329 | 
 | 
| marci@281 |    330 |     template<typename MutableGraph> bool augmentOnBlockingFlow() {      
 | 
| marci@281 |    331 |       typedef MutableGraph MG;
 | 
| marci@281 |    332 |       bool _augment=false;
 | 
| marci@281 |    333 | 
 | 
| marci@281 |    334 |       ResGW res_graph(*g, *flow, *capacity);
 | 
| marci@281 |    335 | 
 | 
| marci@281 |    336 |       typedef typename ResGW::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    337 |       BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
 | 
| marci@281 |    338 | 
 | 
| marci@281 |    339 |       bfs.pushAndSetReached(s);
 | 
| marci@281 |    340 |       //typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
 | 
| marci@281 |    341 |       DistanceMap<ResGW> dist(res_graph);
 | 
| marci@281 |    342 |       while ( !bfs.finished() ) { 
 | 
| marci@281 |    343 | 	ResGWOutEdgeIt e=bfs;
 | 
| marci@281 |    344 | 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    345 | 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
 | 
| marci@281 |    346 | 	}
 | 
| marci@281 |    347 | 	++bfs;
 | 
| marci@281 |    348 |       } //computing distances from s in the residual graph
 | 
| marci@281 |    349 | 
 | 
| marci@281 |    350 |       MG F;
 | 
| marci@281 |    351 |       typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
 | 
| marci@281 |    352 |       FilterResGW filter_res_graph(res_graph, dist);
 | 
| marci@281 |    353 |       typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
 | 
| marci@281 |    354 |       {
 | 
| marci@281 |    355 | 	typename ResGW::NodeIt n;
 | 
| marci@281 |    356 | 	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
 | 
| marci@281 |    357 | 	  res_graph_to_F.set(n, F.addNode());
 | 
| marci@281 |    358 | 	}
 | 
| marci@281 |    359 |       }
 | 
| marci@281 |    360 | 
 | 
| marci@281 |    361 |       typename MG::Node sF=res_graph_to_F.get(s);
 | 
| marci@281 |    362 |       typename MG::Node tF=res_graph_to_F.get(t);
 | 
| marci@281 |    363 |       typename MG::EdgeMap<ResGWEdge> original_edge(F);
 | 
| marci@281 |    364 |       typename MG::EdgeMap<Number> residual_capacity(F);
 | 
| marci@281 |    365 | 
 | 
| marci@281 |    366 |       //Making F to the graph containing the edges of the residual graph 
 | 
| marci@281 |    367 |       //which are in some shortest paths
 | 
| marci@281 |    368 |       {
 | 
| marci@281 |    369 | 	typename FilterResGW::EdgeIt e;
 | 
| marci@281 |    370 | 	for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) {
 | 
| marci@281 |    371 | 	  //if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
 | 
| marci@281 |    372 | 	  typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
 | 
| marci@281 |    373 | 	  original_edge.update();
 | 
| marci@281 |    374 | 	  original_edge.set(f, e);
 | 
| marci@281 |    375 | 	  residual_capacity.update();
 | 
| marci@281 |    376 | 	  residual_capacity.set(f, res_graph.resCap(e));
 | 
| marci@281 |    377 | 	  //} 
 | 
| marci@281 |    378 | 	}
 | 
| marci@281 |    379 |       }
 | 
| marci@281 |    380 | 
 | 
| marci@281 |    381 |       bool __augment=true;
 | 
| marci@281 |    382 | 
 | 
| marci@281 |    383 |       while (__augment) {
 | 
| marci@281 |    384 | 	__augment=false;
 | 
| marci@281 |    385 | 	//computing blocking flow with dfs
 | 
| marci@281 |    386 | 	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
 | 
| marci@281 |    387 | 	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
 | 
| marci@281 |    388 | 	typename MG::NodeMap<typename MG::Edge> pred(F);
 | 
| marci@281 |    389 | 	pred.set(sF, INVALID);
 | 
| marci@281 |    390 | 	//invalid iterators for sources
 | 
| marci@281 |    391 | 
 | 
| marci@281 |    392 | 	typename MG::NodeMap<Number> free(F);
 | 
| marci@281 |    393 | 
 | 
| marci@281 |    394 | 	dfs.pushAndSetReached(sF);      
 | 
| marci@281 |    395 | 	while (!dfs.finished()) {
 | 
| marci@281 |    396 | 	  ++dfs;
 | 
| marci@281 |    397 | 	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
 | 
| marci@281 |    398 | 	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    399 | 	      typename MG::Node v=F.aNode(dfs);
 | 
| marci@281 |    400 | 	      typename MG::Node w=F.bNode(dfs);
 | 
| marci@281 |    401 | 	      pred.set(w, dfs);
 | 
| marci@281 |    402 | 	      if (F.valid(pred.get(v))) {
 | 
| marci@281 |    403 | 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
 | 
| marci@281 |    404 | 	      } else {
 | 
| marci@281 |    405 | 		free.set(w, residual_capacity.get(dfs)); 
 | 
| marci@281 |    406 | 	      }
 | 
| marci@281 |    407 | 	      if (w==tF) { 
 | 
| marci@281 |    408 | 		__augment=true; 
 | 
| marci@281 |    409 | 		_augment=true;
 | 
| marci@281 |    410 | 		break; 
 | 
| marci@281 |    411 | 	      }
 | 
| marci@281 |    412 | 	      
 | 
| marci@281 |    413 | 	    } else {
 | 
| marci@281 |    414 | 	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
 | 
| marci@281 |    415 | 	    }
 | 
| marci@281 |    416 | 	  } 
 | 
| marci@281 |    417 | 	}
 | 
| marci@281 |    418 | 
 | 
| marci@281 |    419 | 	if (__augment) {
 | 
| marci@281 |    420 | 	  typename MG::Node n=tF;
 | 
| marci@281 |    421 | 	  Number augment_value=free.get(tF);
 | 
| marci@281 |    422 | 	  while (F.valid(pred.get(n))) { 
 | 
| marci@281 |    423 | 	    typename MG::Edge e=pred.get(n);
 | 
| marci@281 |    424 | 	    res_graph.augment(original_edge.get(e), augment_value); 
 | 
| marci@281 |    425 | 	    n=F.tail(e);
 | 
| marci@281 |    426 | 	    if (residual_capacity.get(e)==augment_value) 
 | 
| marci@281 |    427 | 	      F.erase(e); 
 | 
| marci@281 |    428 | 	    else 
 | 
| marci@281 |    429 | 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
 | 
| marci@281 |    430 | 	  }
 | 
| marci@281 |    431 | 	}
 | 
| marci@281 |    432 | 	
 | 
| marci@281 |    433 |       }
 | 
| marci@281 |    434 |             
 | 
| marci@281 |    435 |       return _augment;
 | 
| marci@281 |    436 |     }
 | 
| marci@281 |    437 | 
 | 
| marci@281 |    438 |     template<typename MutableGraph> bool augmentOnBlockingFlow1() {      
 | 
| marci@281 |    439 |       typedef MutableGraph MG;
 | 
| marci@281 |    440 |       bool _augment=false;
 | 
| marci@281 |    441 | 
 | 
| marci@281 |    442 |       ResGW res_graph(*g, *flow, *capacity);
 | 
| marci@281 |    443 | 
 | 
| marci@281 |    444 |       //bfs for distances on the residual graph
 | 
| marci@281 |    445 |       typedef typename ResGW::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    446 |       BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
 | 
| marci@281 |    447 |       bfs.pushAndSetReached(s);
 | 
| marci@281 |    448 |       typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
 | 
| marci@281 |    449 | 
 | 
| marci@281 |    450 |       //F will contain the physical copy of the residual graph
 | 
| marci@281 |    451 |       //with the set of edges which are on shortest paths
 | 
| marci@281 |    452 |       MG F;
 | 
| marci@281 |    453 |       typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
 | 
| marci@281 |    454 |       {
 | 
| marci@281 |    455 | 	typename ResGW::NodeIt n;
 | 
| marci@281 |    456 | 	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
 | 
| marci@281 |    457 | 	  res_graph_to_F.set(n, F.addNode());
 | 
| marci@281 |    458 | 	}
 | 
| marci@281 |    459 |       }
 | 
| marci@281 |    460 | 
 | 
| marci@281 |    461 |       typename MG::Node sF=res_graph_to_F.get(s);
 | 
| marci@281 |    462 |       typename MG::Node tF=res_graph_to_F.get(t);
 | 
| marci@281 |    463 |       typename MG::EdgeMap<ResGWEdge> original_edge(F);
 | 
| marci@281 |    464 |       typename MG::EdgeMap<Number> residual_capacity(F);
 | 
| marci@281 |    465 | 
 | 
| marci@281 |    466 |       while ( !bfs.finished() ) { 
 | 
| marci@281 |    467 | 	ResGWOutEdgeIt e=bfs;
 | 
| marci@281 |    468 | 	if (res_graph.valid(e)) {
 | 
| marci@281 |    469 | 	  if (bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    470 | 	    dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
 | 
| marci@281 |    471 | 	    typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
 | 
| marci@281 |    472 | 	    original_edge.update();
 | 
| marci@281 |    473 | 	    original_edge.set(f, e);
 | 
| marci@281 |    474 | 	    residual_capacity.update();
 | 
| marci@281 |    475 | 	    residual_capacity.set(f, res_graph.resCap(e));
 | 
| marci@281 |    476 | 	  } else {
 | 
| marci@281 |    477 | 	    if (dist.get(res_graph.head(e))==(dist.get(res_graph.tail(e))+1)) {
 | 
| marci@281 |    478 | 	      typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
 | 
| marci@281 |    479 | 	      original_edge.update();
 | 
| marci@281 |    480 | 	      original_edge.set(f, e);
 | 
| marci@281 |    481 | 	      residual_capacity.update();
 | 
| marci@281 |    482 | 	      residual_capacity.set(f, res_graph.resCap(e));
 | 
| marci@281 |    483 | 	    }
 | 
| marci@281 |    484 | 	  }
 | 
| marci@281 |    485 | 	}
 | 
| marci@281 |    486 | 	++bfs;
 | 
| marci@281 |    487 |       } //computing distances from s in the residual graph
 | 
| marci@281 |    488 | 
 | 
| marci@281 |    489 |       bool __augment=true;
 | 
| marci@281 |    490 | 
 | 
| marci@281 |    491 |       while (__augment) {
 | 
| marci@281 |    492 | 	__augment=false;
 | 
| marci@281 |    493 | 	//computing blocking flow with dfs
 | 
| marci@281 |    494 | 	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
 | 
| marci@281 |    495 | 	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
 | 
| marci@281 |    496 | 	typename MG::NodeMap<typename MG::Edge> pred(F);
 | 
| marci@281 |    497 | 	pred.set(sF, INVALID);
 | 
| marci@281 |    498 | 	//invalid iterators for sources
 | 
| marci@281 |    499 | 
 | 
| marci@281 |    500 | 	typename MG::NodeMap<Number> free(F);
 | 
| marci@281 |    501 | 
 | 
| marci@281 |    502 | 	dfs.pushAndSetReached(sF);      
 | 
| marci@281 |    503 | 	while (!dfs.finished()) {
 | 
| marci@281 |    504 | 	  ++dfs;
 | 
| marci@281 |    505 | 	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
 | 
| marci@281 |    506 | 	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    507 | 	      typename MG::Node v=F.aNode(dfs);
 | 
| marci@281 |    508 | 	      typename MG::Node w=F.bNode(dfs);
 | 
| marci@281 |    509 | 	      pred.set(w, dfs);
 | 
| marci@281 |    510 | 	      if (F.valid(pred.get(v))) {
 | 
| marci@281 |    511 | 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
 | 
| marci@281 |    512 | 	      } else {
 | 
| marci@281 |    513 | 		free.set(w, residual_capacity.get(dfs)); 
 | 
| marci@281 |    514 | 	      }
 | 
| marci@281 |    515 | 	      if (w==tF) { 
 | 
| marci@281 |    516 | 		__augment=true; 
 | 
| marci@281 |    517 | 		_augment=true;
 | 
| marci@281 |    518 | 		break; 
 | 
| marci@281 |    519 | 	      }
 | 
| marci@281 |    520 | 	      
 | 
| marci@281 |    521 | 	    } else {
 | 
| marci@281 |    522 | 	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
 | 
| marci@281 |    523 | 	    }
 | 
| marci@281 |    524 | 	  } 
 | 
| marci@281 |    525 | 	}
 | 
| marci@281 |    526 | 
 | 
| marci@281 |    527 | 	if (__augment) {
 | 
| marci@281 |    528 | 	  typename MG::Node n=tF;
 | 
| marci@281 |    529 | 	  Number augment_value=free.get(tF);
 | 
| marci@281 |    530 | 	  while (F.valid(pred.get(n))) { 
 | 
| marci@281 |    531 | 	    typename MG::Edge e=pred.get(n);
 | 
| marci@281 |    532 | 	    res_graph.augment(original_edge.get(e), augment_value); 
 | 
| marci@281 |    533 | 	    n=F.tail(e);
 | 
| marci@281 |    534 | 	    if (residual_capacity.get(e)==augment_value) 
 | 
| marci@281 |    535 | 	      F.erase(e); 
 | 
| marci@281 |    536 | 	    else 
 | 
| marci@281 |    537 | 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
 | 
| marci@281 |    538 | 	  }
 | 
| marci@281 |    539 | 	}
 | 
| marci@281 |    540 | 	
 | 
| marci@281 |    541 |       }
 | 
| marci@281 |    542 |             
 | 
| marci@281 |    543 |       return _augment;
 | 
| marci@281 |    544 |     }
 | 
| marci@281 |    545 | 
 | 
| marci@281 |    546 |     bool augmentOnBlockingFlow2() {
 | 
| marci@281 |    547 |       bool _augment=false;
 | 
| marci@281 |    548 | 
 | 
| marci@281 |    549 |       ResGW res_graph(*g, *flow, *capacity);
 | 
| marci@281 |    550 | 
 | 
| marci@281 |    551 |       typedef typename ResGW::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    552 |       BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
 | 
| marci@281 |    553 | 
 | 
| marci@281 |    554 |       bfs.pushAndSetReached(s);
 | 
| marci@281 |    555 |       DistanceMap<ResGW> dist(res_graph);
 | 
| marci@281 |    556 |       while ( !bfs.finished() ) { 
 | 
| marci@281 |    557 |  	ResGWOutEdgeIt e=bfs;
 | 
| marci@281 |    558 |  	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    559 |  	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
 | 
| marci@281 |    560 |  	}
 | 
| marci@281 |    561 | 	++bfs;
 | 
| marci@281 |    562 |       } //computing distances from s in the residual graph
 | 
| marci@281 |    563 | 
 | 
| marci@281 |    564 |       //Subgraph containing the edges on some shortest paths
 | 
| marci@281 |    565 |       typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
 | 
| marci@281 |    566 |       FilterResGW filter_res_graph(res_graph, dist);
 | 
| marci@281 |    567 | 
 | 
| marci@281 |    568 |       //Subgraph, which is able to delete edges which are already 
 | 
| marci@281 |    569 |       //met by the dfs
 | 
| marci@281 |    570 |       typename FilterResGW::NodeMap<typename FilterResGW::OutEdgeIt> 
 | 
| marci@281 |    571 |  	first_out_edges(filter_res_graph);
 | 
| marci@281 |    572 |       typename FilterResGW::NodeIt v;
 | 
| marci@281 |    573 |       for(filter_res_graph.first(v); filter_res_graph.valid(v); 
 | 
| marci@281 |    574 |  	  filter_res_graph.next(v)) 
 | 
| marci@281 |    575 |       {
 | 
| marci@281 |    576 |  	typename FilterResGW::OutEdgeIt e;
 | 
| marci@281 |    577 |  	filter_res_graph.first(e, v);
 | 
| marci@281 |    578 |  	first_out_edges.set(v, e);
 | 
| marci@281 |    579 |       }
 | 
| marci@281 |    580 |       typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
 | 
| marci@281 |    581 | 	NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
 | 
| marci@281 |    582 |       ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
 | 
| marci@281 |    583 | 
 | 
| marci@281 |    584 |       bool __augment=true;
 | 
| marci@281 |    585 | 
 | 
| marci@281 |    586 |       while (__augment) {
 | 
| marci@281 |    587 | 
 | 
| marci@281 |    588 |  	__augment=false;
 | 
| marci@281 |    589 |  	//computing blocking flow with dfs
 | 
| marci@281 |    590 | 	typedef typename ErasingResGW::NodeMap<bool> BlockingReachedMap;
 | 
| marci@281 |    591 |  	DfsIterator5< ErasingResGW, BlockingReachedMap > 
 | 
| marci@281 |    592 |  	  dfs(erasing_res_graph);
 | 
| marci@281 |    593 |  	typename ErasingResGW::NodeMap<typename ErasingResGW::OutEdgeIt> 
 | 
| marci@281 |    594 |  	  pred(erasing_res_graph); 
 | 
| marci@281 |    595 |  	pred.set(s, INVALID);
 | 
| marci@281 |    596 |  	//invalid iterators for sources
 | 
| marci@281 |    597 | 
 | 
| marci@281 |    598 |  	typename ErasingResGW::NodeMap<Number> free(erasing_res_graph);
 | 
| marci@281 |    599 | 
 | 
| marci@281 |    600 |  	dfs.pushAndSetReached(s);
 | 
| marci@281 |    601 |  	while (!dfs.finished()) {
 | 
| marci@281 |    602 |  	  ++dfs;
 | 
| marci@281 |    603 |  	  if (erasing_res_graph.valid(
 | 
| marci@281 |    604 |  		/*typename ErasingResGW::OutEdgeIt*/(dfs))) 
 | 
| marci@281 |    605 |  	  { 
 | 
| marci@281 |    606 |  	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    607 | 	  
 | 
| marci@281 |    608 |  	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
 | 
| marci@281 |    609 |  	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
 | 
| marci@281 |    610 | 
 | 
| marci@281 |    611 |  	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
 | 
| marci@281 |    612 |  	      if (erasing_res_graph.valid(pred.get(v))) {
 | 
| marci@281 |    613 |  		free.set(w, std::min(free.get(v), res_graph.resCap(dfs)));
 | 
| marci@281 |    614 |  	      } else {
 | 
| marci@281 |    615 |  		free.set(w, res_graph.resCap(dfs)); 
 | 
| marci@281 |    616 |  	      }
 | 
| marci@281 |    617 | 	      
 | 
| marci@281 |    618 |  	      if (w==t) { 
 | 
| marci@281 |    619 |  		__augment=true; 
 | 
| marci@281 |    620 |  		_augment=true;
 | 
| marci@281 |    621 |  		break; 
 | 
| marci@281 |    622 |  	      }
 | 
| marci@281 |    623 | 	    } else {
 | 
| marci@281 |    624 | 	      erasing_res_graph.erase(dfs);
 | 
| marci@281 |    625 | 	    }
 | 
| marci@281 |    626 | 	  }
 | 
| marci@281 |    627 | 	}	
 | 
| marci@281 |    628 | 
 | 
| marci@281 |    629 |  	if (__augment) {
 | 
| marci@281 |    630 |  	  typename ErasingResGW::Node n=t;
 | 
| marci@281 |    631 |  	  Number augment_value=free.get(n);
 | 
| marci@281 |    632 |  	  while (erasing_res_graph.valid(pred.get(n))) { 
 | 
| marci@281 |    633 |  	    typename ErasingResGW::OutEdgeIt e=pred.get(n);
 | 
| marci@281 |    634 |  	    res_graph.augment(e, augment_value);
 | 
| marci@281 |    635 |  	    n=erasing_res_graph.tail(e);
 | 
| marci@281 |    636 |  	    if (res_graph.resCap(e)==0)
 | 
| marci@281 |    637 |  	      erasing_res_graph.erase(e);
 | 
| marci@281 |    638 |  	  }
 | 
| marci@281 |    639 |  	}
 | 
| marci@281 |    640 |       
 | 
| marci@281 |    641 |       } //while (__augment) 
 | 
| marci@281 |    642 |             
 | 
| marci@281 |    643 |       return _augment;
 | 
| marci@281 |    644 |     }
 | 
| marci@281 |    645 | 
 | 
| marci@281 |    646 |     void run() {
 | 
| marci@281 |    647 |       //int num_of_augmentations=0;
 | 
| marci@281 |    648 |       while (augmentOnShortestPath()) { 
 | 
| marci@281 |    649 | 	//while (augmentOnBlockingFlow<MutableGraph>()) { 
 | 
| marci@281 |    650 | 	//std::cout << ++num_of_augmentations << " ";
 | 
| marci@281 |    651 | 	//std::cout<<std::endl;
 | 
| marci@281 |    652 |       } 
 | 
| marci@281 |    653 |     }
 | 
| marci@281 |    654 | 
 | 
| marci@281 |    655 |     template<typename MutableGraph> void run() {
 | 
| marci@281 |    656 |       //int num_of_augmentations=0;
 | 
| marci@281 |    657 |       //while (augmentOnShortestPath()) { 
 | 
| marci@281 |    658 | 	while (augmentOnBlockingFlow<MutableGraph>()) { 
 | 
| marci@281 |    659 | 	//std::cout << ++num_of_augmentations << " ";
 | 
| marci@281 |    660 | 	//std::cout<<std::endl;
 | 
| marci@281 |    661 |       } 
 | 
| marci@281 |    662 |     }
 | 
| marci@281 |    663 | 
 | 
| marci@281 |    664 |     Number flowValue() { 
 | 
| marci@281 |    665 |       Number a=0;
 | 
| marci@281 |    666 |       OutEdgeIt e;
 | 
| marci@281 |    667 |       for(g->first(e, s); g->valid(e); g->next(e)) {
 | 
| marci@281 |    668 | 	a+=flow->get(e);
 | 
| marci@281 |    669 |       }
 | 
| marci@281 |    670 |       return a;
 | 
| marci@281 |    671 |     }
 | 
| marci@281 |    672 | 
 | 
| marci@281 |    673 |   };
 | 
| marci@281 |    674 | 
 | 
| marci@281 |    675 | 
 | 
| marci@281 |    676 | //   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
 | 
| marci@281 |    677 | //   class MaxMatching {
 | 
| marci@281 |    678 | //   public:
 | 
| marci@281 |    679 | //     typedef typename Graph::Node Node;
 | 
| marci@281 |    680 | //     typedef typename Graph::NodeIt NodeIt;
 | 
| marci@281 |    681 | //     typedef typename Graph::Edge Edge;
 | 
| marci@281 |    682 | //     typedef typename Graph::EdgeIt EdgeIt;
 | 
| marci@281 |    683 | //     typedef typename Graph::OutEdgeIt OutEdgeIt;
 | 
| marci@281 |    684 | //     typedef typename Graph::InEdgeIt InEdgeIt;
 | 
| marci@281 |    685 | 
 | 
| marci@281 |    686 | //     typedef typename Graph::NodeMap<bool> SMap;
 | 
| marci@281 |    687 | //     typedef typename Graph::NodeMap<bool> TMap;
 | 
| marci@281 |    688 | //   private:
 | 
| marci@281 |    689 | //     const Graph* G;
 | 
| marci@281 |    690 | //     SMap* S;
 | 
| marci@281 |    691 | //     TMap* T;
 | 
| marci@281 |    692 | //     //Node s;
 | 
| marci@281 |    693 | //     //Node t;
 | 
| marci@281 |    694 | //     FlowMap* flow;
 | 
| marci@281 |    695 | //     const CapacityMap* capacity;
 | 
| marci@281 |    696 | //     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
 | 
| marci@281 |    697 | //     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
 | 
| marci@281 |    698 | //     typedef typename AugGraph::Edge AugEdge;
 | 
| marci@281 |    699 | //     typename Graph::NodeMap<int> used; //0
 | 
| marci@281 |    700 | 
 | 
| marci@281 |    701 | //   public:
 | 
| marci@281 |    702 | //     MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapacityMap& _capacity) : 
 | 
| marci@281 |    703 | //       G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { }
 | 
| marci@281 |    704 | //     bool augmentOnShortestPath() {
 | 
| marci@281 |    705 | //       AugGraph res_graph(*G, *flow, *capacity);
 | 
| marci@281 |    706 | //       bool _augment=false;
 | 
| marci@281 |    707 |       
 | 
| marci@281 |    708 | //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    709 | //       BfsIterator5< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph);
 | 
| marci@281 |    710 | //       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
 | 
| marci@281 |    711 | //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
 | 
| marci@281 |    712 | // 	if ((S->get(s)) && (used.get(s)<1) ) {
 | 
| marci@281 |    713 | // 	  //Number u=0;
 | 
| marci@281 |    714 | // 	  //for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
 | 
| marci@281 |    715 | // 	  //u+=flow->get(e);
 | 
| marci@281 |    716 | // 	  //if (u<1) {
 | 
| marci@281 |    717 | // 	    bfs.pushAndSetReached(s);
 | 
| marci@281 |    718 | // 	    pred.set(s, AugEdge(INVALID));
 | 
| marci@281 |    719 | // 	    //}
 | 
| marci@281 |    720 | // 	}
 | 
| marci@281 |    721 | //       }
 | 
| marci@281 |    722 |       
 | 
| marci@281 |    723 | //       typename AugGraph::NodeMap<Number> free(res_graph);
 | 
| marci@281 |    724 | 	
 | 
| marci@281 |    725 | //       Node n;
 | 
| marci@281 |    726 | //       //searching for augmenting path
 | 
| marci@281 |    727 | //       while ( !bfs.finished() ) { 
 | 
| marci@281 |    728 | // 	AugOutEdgeIt e=bfs;
 | 
| marci@281 |    729 | // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    730 | // 	  Node v=res_graph.tail(e);
 | 
| marci@281 |    731 | // 	  Node w=res_graph.head(e);
 | 
| marci@281 |    732 | // 	  pred.set(w, e);
 | 
| marci@281 |    733 | // 	  if (res_graph.valid(pred.get(v))) {
 | 
| marci@281 |    734 | // 	    free.set(w, std::min(free.get(v), res_graph.free(e)));
 | 
| marci@281 |    735 | // 	  } else {
 | 
| marci@281 |    736 | // 	    free.set(w, res_graph.free(e)); 
 | 
| marci@281 |    737 | // 	  }
 | 
| marci@281 |    738 | // 	  n=res_graph.head(e);
 | 
| marci@281 |    739 | // 	  if (T->get(n) && (used.get(n)<1) ) { 
 | 
| marci@281 |    740 | // 	    //Number u=0;
 | 
| marci@281 |    741 | // 	    //for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
 | 
| marci@281 |    742 | // 	    //u+=flow->get(f);
 | 
| marci@281 |    743 | // 	    //if (u<1) {
 | 
| marci@281 |    744 | // 	      _augment=true; 
 | 
| marci@281 |    745 | // 	      break; 
 | 
| marci@281 |    746 | // 	      //}
 | 
| marci@281 |    747 | // 	  }
 | 
| marci@281 |    748 | // 	}
 | 
| marci@281 |    749 | 	
 | 
| marci@281 |    750 | // 	++bfs;
 | 
| marci@281 |    751 | //       } //end of searching augmenting path
 | 
| marci@281 |    752 | 
 | 
| marci@281 |    753 | //       if (_augment) {
 | 
| marci@281 |    754 | // 	//Node n=t;
 | 
| marci@281 |    755 | // 	used.set(n, 1); //mind2 vegen jav
 | 
| marci@281 |    756 | // 	Number augment_value=free.get(n);
 | 
| marci@281 |    757 | // 	while (res_graph.valid(pred.get(n))) { 
 | 
| marci@281 |    758 | // 	  AugEdge e=pred.get(n);
 | 
| marci@281 |    759 | // 	  res_graph.augment(e, augment_value); 
 | 
| marci@281 |    760 | // 	  n=res_graph.tail(e);
 | 
| marci@281 |    761 | // 	}
 | 
| marci@281 |    762 | // 	used.set(n, 1); //mind2 vegen jav
 | 
| marci@281 |    763 | //       }
 | 
| marci@281 |    764 | 
 | 
| marci@281 |    765 | //       return _augment;
 | 
| marci@281 |    766 | //     }
 | 
| marci@281 |    767 | 
 | 
| marci@281 |    768 | // //     template<typename MutableGraph> bool augmentOnBlockingFlow() {      
 | 
| marci@281 |    769 | // //       bool _augment=false;
 | 
| marci@281 |    770 | 
 | 
| marci@281 |    771 | // //       AugGraph res_graph(*G, *flow, *capacity);
 | 
| marci@281 |    772 | 
 | 
| marci@281 |    773 | // //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    774 | // //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
 | 
| marci@281 |    775 | 
 | 
| marci@281 |    776 | 
 | 
| marci@281 |    777 | 
 | 
| marci@281 |    778 | 
 | 
| marci@281 |    779 | 
 | 
| marci@281 |    780 | // //       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
 | 
| marci@281 |    781 | // //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
 | 
| marci@281 |    782 | // // 	if (S->get(s)) {
 | 
| marci@281 |    783 | // // 	  Number u=0;
 | 
| marci@281 |    784 | // // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
 | 
| marci@281 |    785 | // // 	    u+=flow->get(e);
 | 
| marci@281 |    786 | // // 	  if (u<1) {
 | 
| marci@281 |    787 | // // 	    bfs.pushAndSetReached(s);
 | 
| marci@281 |    788 | // // 	    //pred.set(s, AugEdge(INVALID));
 | 
| marci@281 |    789 | // // 	  }
 | 
| marci@281 |    790 | // // 	}
 | 
| marci@281 |    791 | // //       }
 | 
| marci@281 |    792 | 
 | 
| marci@281 |    793 | 
 | 
| marci@281 |    794 | 
 | 
| marci@281 |    795 | 
 | 
| marci@281 |    796 | // //       //bfs.pushAndSetReached(s);
 | 
| marci@281 |    797 | // //       typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
 | 
| marci@281 |    798 | // //       while ( !bfs.finished() ) { 
 | 
| marci@281 |    799 | // // 	AugOutEdgeIt e=bfs;
 | 
| marci@281 |    800 | // // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    801 | // // 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
 | 
| marci@281 |    802 | // // 	}
 | 
| marci@281 |    803 | 	
 | 
| marci@281 |    804 | // // 	++bfs;
 | 
| marci@281 |    805 | // //       } //computing distances from s in the residual graph
 | 
| marci@281 |    806 | 
 | 
| marci@281 |    807 | // //       MutableGraph F;
 | 
| marci@281 |    808 | // //       typename AugGraph::NodeMap<typename MutableGraph::Node> 
 | 
| marci@281 |    809 | // // 	res_graph_to_F(res_graph);
 | 
| marci@281 |    810 | // //       for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
 | 
| marci@281 |    811 | // // 	res_graph_to_F.set(n, F.addNode());
 | 
| marci@281 |    812 | // //       }
 | 
| marci@281 |    813 |       
 | 
| marci@281 |    814 | // //       typename MutableGraph::Node sF=res_graph_to_F.get(s);
 | 
| marci@281 |    815 | // //       typename MutableGraph::Node tF=res_graph_to_F.get(t);
 | 
| marci@281 |    816 | 
 | 
| marci@281 |    817 | // //       typename MutableGraph::EdgeMap<AugEdge> original_edge(F);
 | 
| marci@281 |    818 | // //       typename MutableGraph::EdgeMap<Number> residual_capacity(F);
 | 
| marci@281 |    819 | 
 | 
| marci@281 |    820 | // //       //Making F to the graph containing the edges of the residual graph 
 | 
| marci@281 |    821 | // //       //which are in some shortest paths
 | 
| marci@281 |    822 | // //       for(typename AugGraph::EdgeIt e=res_graph.template first<typename AugGraph::EdgeIt>(); res_graph.valid(e); res_graph.next(e)) {
 | 
| marci@281 |    823 | // // 	if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
 | 
| marci@281 |    824 | // // 	  typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
 | 
| marci@281 |    825 | // // 	  original_edge.update();
 | 
| marci@281 |    826 | // // 	  original_edge.set(f, e);
 | 
| marci@281 |    827 | // // 	  residual_capacity.update();
 | 
| marci@281 |    828 | // // 	  residual_capacity.set(f, res_graph.free(e));
 | 
| marci@281 |    829 | // // 	} 
 | 
| marci@281 |    830 | // //       }
 | 
| marci@281 |    831 | 
 | 
| marci@281 |    832 | // //       bool __augment=true;
 | 
| marci@281 |    833 | 
 | 
| marci@281 |    834 | // //       while (__augment) {
 | 
| marci@281 |    835 | // // 	__augment=false;
 | 
| marci@281 |    836 | // // 	//computing blocking flow with dfs
 | 
| marci@281 |    837 | // // 	typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
 | 
| marci@281 |    838 | // // 	DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
 | 
| marci@281 |    839 | // // 	typename MutableGraph::NodeMap<typename MutableGraph::Edge> pred(F);
 | 
| marci@281 |    840 | // // 	pred.set(sF, typename MutableGraph::Edge(INVALID));
 | 
| marci@281 |    841 | // // 	//invalid iterators for sources
 | 
| marci@281 |    842 | 
 | 
| marci@281 |    843 | // // 	typename MutableGraph::NodeMap<Number> free(F);
 | 
| marci@281 |    844 | 
 | 
| marci@281 |    845 | // // 	dfs.pushAndSetReached(sF);      
 | 
| marci@281 |    846 | // // 	while (!dfs.finished()) {
 | 
| marci@281 |    847 | // // 	  ++dfs;
 | 
| marci@281 |    848 | // // 	  if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) {
 | 
| marci@281 |    849 | // // 	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    850 | // // 	      typename MutableGraph::Node v=F.aNode(dfs);
 | 
| marci@281 |    851 | // // 	      typename MutableGraph::Node w=F.bNode(dfs);
 | 
| marci@281 |    852 | // // 	      pred.set(w, dfs);
 | 
| marci@281 |    853 | // // 	      if (F.valid(pred.get(v))) {
 | 
| marci@281 |    854 | // // 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
 | 
| marci@281 |    855 | // // 	      } else {
 | 
| marci@281 |    856 | // // 		free.set(w, residual_capacity.get(dfs)); 
 | 
| marci@281 |    857 | // // 	      }
 | 
| marci@281 |    858 | // // 	      if (w==tF) { 
 | 
| marci@281 |    859 | // // 		__augment=true; 
 | 
| marci@281 |    860 | // // 		_augment=true;
 | 
| marci@281 |    861 | // // 		break; 
 | 
| marci@281 |    862 | // // 	      }
 | 
| marci@281 |    863 | 	      
 | 
| marci@281 |    864 | // // 	    } else {
 | 
| marci@281 |    865 | // // 	      F.erase(typename MutableGraph::OutEdgeIt(dfs));
 | 
| marci@281 |    866 | // // 	    }
 | 
| marci@281 |    867 | // // 	  } 
 | 
| marci@281 |    868 | // // 	}
 | 
| marci@281 |    869 | 
 | 
| marci@281 |    870 | // // 	if (__augment) {
 | 
| marci@281 |    871 | // // 	  typename MutableGraph::Node n=tF;
 | 
| marci@281 |    872 | // // 	  Number augment_value=free.get(tF);
 | 
| marci@281 |    873 | // // 	  while (F.valid(pred.get(n))) { 
 | 
| marci@281 |    874 | // // 	    typename MutableGraph::Edge e=pred.get(n);
 | 
| marci@281 |    875 | // // 	    res_graph.augment(original_edge.get(e), augment_value); 
 | 
| marci@281 |    876 | // // 	    n=F.tail(e);
 | 
| marci@281 |    877 | // // 	    if (residual_capacity.get(e)==augment_value) 
 | 
| marci@281 |    878 | // // 	      F.erase(e); 
 | 
| marci@281 |    879 | // // 	    else 
 | 
| marci@281 |    880 | // // 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
 | 
| marci@281 |    881 | // // 	  }
 | 
| marci@281 |    882 | // // 	}
 | 
| marci@281 |    883 | 	
 | 
| marci@281 |    884 | // //       }
 | 
| marci@281 |    885 |             
 | 
| marci@281 |    886 | // //       return _augment;
 | 
| marci@281 |    887 | // //     }
 | 
| marci@281 |    888 | //     bool augmentOnBlockingFlow2() {
 | 
| marci@281 |    889 | //       bool _augment=false;
 | 
| marci@281 |    890 | 
 | 
| marci@281 |    891 | //       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
 | 
| marci@281 |    892 | //       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
 | 
| marci@281 |    893 | //       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
 | 
| marci@281 |    894 | //       typedef typename EAugGraph::Edge EAugEdge;
 | 
| marci@281 |    895 | 
 | 
| marci@281 |    896 | //       EAugGraph res_graph(*G, *flow, *capacity);
 | 
| marci@281 |    897 | 
 | 
| marci@281 |    898 | //       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
 | 
| marci@281 |    899 | //       BfsIterator5< 
 | 
| marci@281 |    900 | // 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
 | 
| marci@281 |    901 | // 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
 | 
| marci@281 |    902 | // 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
 | 
| marci@281 |    903 | 
 | 
| marci@281 |    904 | 
 | 
| marci@281 |    905 | //       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
 | 
| marci@281 |    906 | //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
 | 
| marci@281 |    907 | // 	if (S->get(s)) {
 | 
| marci@281 |    908 | // 	  Number u=0;
 | 
| marci@281 |    909 | // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
 | 
| marci@281 |    910 | // 	    u+=flow->get(e);
 | 
| marci@281 |    911 | // 	  if (u<1) {
 | 
| marci@281 |    912 | // 	    bfs.pushAndSetReached(s);
 | 
| marci@281 |    913 | // 	    //pred.set(s, AugEdge(INVALID));
 | 
| marci@281 |    914 | // 	  }
 | 
| marci@281 |    915 | // 	}
 | 
| marci@281 |    916 | //       }
 | 
| marci@281 |    917 | 
 | 
| marci@281 |    918 |       
 | 
| marci@281 |    919 | //       //bfs.pushAndSetReached(s);
 | 
| marci@281 |    920 | 
 | 
| marci@281 |    921 | //       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
 | 
| marci@281 |    922 | // 	NodeMap<int>& dist=res_graph.dist;
 | 
| marci@281 |    923 | 
 | 
| marci@281 |    924 | //       while ( !bfs.finished() ) {
 | 
| marci@281 |    925 | // 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
 | 
| marci@281 |    926 | // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    927 | // 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
 | 
| marci@281 |    928 | // 	}
 | 
| marci@281 |    929 | // 	++bfs;	
 | 
| marci@281 |    930 | //       } //computing distances from s in the residual graph
 | 
| marci@281 |    931 | 
 | 
| marci@281 |    932 | //       bool __augment=true;
 | 
| marci@281 |    933 | 
 | 
| marci@281 |    934 | //       while (__augment) {
 | 
| marci@281 |    935 | 
 | 
| marci@281 |    936 | // 	__augment=false;
 | 
| marci@281 |    937 | // 	//computing blocking flow with dfs
 | 
| marci@281 |    938 | // 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
 | 
| marci@281 |    939 | // 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
 | 
| marci@281 |    940 | // 	  dfs(res_graph);
 | 
| marci@281 |    941 | // 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph, INVALID); 
 | 
| marci@281 |    942 | // 	//pred.set(s, EAugEdge(INVALID));
 | 
| marci@281 |    943 | // 	//invalid iterators for sources
 | 
| marci@281 |    944 | 
 | 
| marci@281 |    945 | // 	typename EAugGraph::NodeMap<Number> free(res_graph);
 | 
| marci@281 |    946 | 
 | 
| marci@281 |    947 | 
 | 
| marci@281 |    948 | // 	//typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
 | 
| marci@281 |    949 | //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
 | 
| marci@281 |    950 | // 	if (S->get(s)) {
 | 
| marci@281 |    951 | // 	  Number u=0;
 | 
| marci@281 |    952 | // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
 | 
| marci@281 |    953 | // 	    u+=flow->get(e);
 | 
| marci@281 |    954 | // 	  if (u<1) {
 | 
| marci@281 |    955 | // 	    dfs.pushAndSetReached(s);
 | 
| marci@281 |    956 | // 	    //pred.set(s, AugEdge(INVALID));
 | 
| marci@281 |    957 | // 	  }
 | 
| marci@281 |    958 | // 	}
 | 
| marci@281 |    959 | //       }
 | 
| marci@281 |    960 | 
 | 
| marci@281 |    961 | 
 | 
| marci@281 |    962 | 
 | 
| marci@281 |    963 | //       //dfs.pushAndSetReached(s);
 | 
| marci@281 |    964 | //       typename EAugGraph::Node n;
 | 
| marci@281 |    965 | // 	while (!dfs.finished()) {
 | 
| marci@281 |    966 | // 	  ++dfs;
 | 
| marci@281 |    967 | // 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
 | 
| marci@281 |    968 | // 	    if (dfs.isBNodeNewlyReached()) {
 | 
| marci@281 |    969 | 	  
 | 
| marci@281 |    970 | // 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
 | 
| marci@281 |    971 | // 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
 | 
| marci@281 |    972 | 
 | 
| marci@281 |    973 | // 	      pred.set(w, EAugOutEdgeIt(dfs));
 | 
| marci@281 |    974 | // 	      if (res_graph.valid(pred.get(v))) {
 | 
| marci@281 |    975 | // 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
 | 
| marci@281 |    976 | // 	      } else {
 | 
| marci@281 |    977 | // 		free.set(w, res_graph.free(dfs)); 
 | 
| marci@281 |    978 | // 	      }
 | 
| marci@281 |    979 | 	     
 | 
| marci@281 |    980 | // 	      n=w;
 | 
| marci@281 |    981 | // 	      if (T->get(w)) {
 | 
| marci@281 |    982 | // 		Number u=0;
 | 
| marci@281 |    983 | // 		for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
 | 
| marci@281 |    984 | // 		  u+=flow->get(f);
 | 
| marci@281 |    985 | // 		if (u<1) {
 | 
| marci@281 |    986 | // 		  __augment=true; 
 | 
| marci@281 |    987 | // 		  _augment=true;
 | 
| marci@281 |    988 | // 		  break; 
 | 
| marci@281 |    989 | // 		}
 | 
| marci@281 |    990 | // 	      }
 | 
| marci@281 |    991 | // 	    } else {
 | 
| marci@281 |    992 | // 	      res_graph.erase(dfs);
 | 
| marci@281 |    993 | // 	    }
 | 
| marci@281 |    994 | // 	  } 
 | 
| marci@281 |    995 | 
 | 
| marci@281 |    996 | // 	}
 | 
| marci@281 |    997 | 
 | 
| marci@281 |    998 | // 	if (__augment) {
 | 
| marci@281 |    999 | // 	  // typename EAugGraph::Node n=t;
 | 
| marci@281 |   1000 | // 	  Number augment_value=free.get(n);
 | 
| marci@281 |   1001 | // 	  while (res_graph.valid(pred.get(n))) { 
 | 
| marci@281 |   1002 | // 	    EAugEdge e=pred.get(n);
 | 
| marci@281 |   1003 | // 	    res_graph.augment(e, augment_value);
 | 
| marci@281 |   1004 | // 	    n=res_graph.tail(e);
 | 
| marci@281 |   1005 | // 	    if (res_graph.free(e)==0)
 | 
| marci@281 |   1006 | // 	      res_graph.erase(e);
 | 
| marci@281 |   1007 | // 	  }
 | 
| marci@281 |   1008 | // 	}
 | 
| marci@281 |   1009 |       
 | 
| marci@281 |   1010 | //       }
 | 
| marci@281 |   1011 |             
 | 
| marci@281 |   1012 | //       return _augment;
 | 
| marci@281 |   1013 | //     }
 | 
| marci@281 |   1014 | //     void run() {
 | 
| marci@281 |   1015 | //       //int num_of_augmentations=0;
 | 
| marci@281 |   1016 | //       while (augmentOnShortestPath()) { 
 | 
| marci@281 |   1017 | // 	//while (augmentOnBlockingFlow<MutableGraph>()) { 
 | 
| marci@281 |   1018 | // 	//std::cout << ++num_of_augmentations << " ";
 | 
| marci@281 |   1019 | // 	//std::cout<<std::endl;
 | 
| marci@281 |   1020 | //       } 
 | 
| marci@281 |   1021 | //     }
 | 
| marci@281 |   1022 | // //     template<typename MutableGraph> void run() {
 | 
| marci@281 |   1023 | // //       //int num_of_augmentations=0;
 | 
| marci@281 |   1024 | // //       //while (augmentOnShortestPath()) { 
 | 
| marci@281 |   1025 | // // 	while (augmentOnBlockingFlow<MutableGraph>()) { 
 | 
| marci@281 |   1026 | // // 	//std::cout << ++num_of_augmentations << " ";
 | 
| marci@281 |   1027 | // // 	//std::cout<<std::endl;
 | 
| marci@281 |   1028 | // //       } 
 | 
| marci@281 |   1029 | // //     } 
 | 
| marci@281 |   1030 | //     Number flowValue() { 
 | 
| marci@281 |   1031 | //       Number a=0;
 | 
| marci@281 |   1032 | //       EdgeIt e;
 | 
| marci@281 |   1033 | //       for(G->/*getF*/first(e); G->valid(e); G->next(e)) {
 | 
| marci@281 |   1034 | // 	a+=flow->get(e);
 | 
| marci@281 |   1035 | //       }
 | 
| marci@281 |   1036 | //       return a;
 | 
| marci@281 |   1037 | //     }
 | 
| marci@281 |   1038 | //   };
 | 
| marci@281 |   1039 | 
 | 
| marci@281 |   1040 | 
 | 
| marci@281 |   1041 | 
 | 
| marci@281 |   1042 | 
 | 
| marci@281 |   1043 | 
 | 
| marci@281 |   1044 |   
 | 
| marci@281 |   1045 | // //   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
 | 
| marci@281 |   1046 | // //   class MaxFlow2 {
 | 
| marci@281 |   1047 | // //   public:
 | 
| marci@281 |   1048 | // //     typedef typename Graph::Node Node;
 | 
| marci@281 |   1049 | // //     typedef typename Graph::Edge Edge;
 | 
| marci@281 |   1050 | // //     typedef typename Graph::EdgeIt EdgeIt;
 | 
| marci@281 |   1051 | // //     typedef typename Graph::OutEdgeIt OutEdgeIt;
 | 
| marci@281 |   1052 | // //     typedef typename Graph::InEdgeIt InEdgeIt;
 | 
| marci@281 |   1053 | // //   private:
 | 
| marci@281 |   1054 | // //     const Graph& G;
 | 
| marci@281 |   1055 | // //     std::list<Node>& S;
 | 
| marci@281 |   1056 | // //     std::list<Node>& T;
 | 
| marci@281 |   1057 | // //     FlowMap& flow;
 | 
| marci@281 |   1058 | // //     const CapacityMap& capacity;
 | 
| marci@281 |   1059 | // //     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
 | 
| marci@281 |   1060 | // //     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
 | 
| marci@281 |   1061 | // //     typedef typename AugGraph::Edge AugEdge;
 | 
| marci@281 |   1062 | // //     typename Graph::NodeMap<bool> SMap;
 | 
| marci@281 |   1063 | // //     typename Graph::NodeMap<bool> TMap;
 | 
| marci@281 |   1064 | // //   public:
 | 
| marci@281 |   1065 | // //     MaxFlow2(const Graph& _G, std::list<Node>& _S, std::list<Node>& _T, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { 
 | 
| marci@281 |   1066 | // //       for(typename std::list<Node>::const_iterator i=S.begin(); 
 | 
| marci@281 |   1067 | // // 	  i!=S.end(); ++i) { 
 | 
| marci@281 |   1068 | // // 	SMap.set(*i, true); 
 | 
| marci@281 |   1069 | // //       }
 | 
| marci@281 |   1070 | // //       for (typename std::list<Node>::const_iterator i=T.begin(); 
 | 
| marci@281 |   1071 | // // 	   i!=T.end(); ++i) { 
 | 
| marci@281 |   1072 | // // 	TMap.set(*i, true); 
 | 
| marci@281 |   1073 | // //       }
 | 
| marci@281 |   1074 | // //     }
 | 
| marci@281 |   1075 | // //     bool augment() {
 | 
| marci@281 |   1076 | // //       AugGraph res_graph(G, flow, capacity);
 | 
| marci@281 |   1077 | // //       bool _augment=false;
 | 
| marci@281 |   1078 | // //       Node reached_t_node;
 | 
| marci@281 |   1079 |       
 | 
| marci@281 |   1080 | // //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
 | 
| marci@281 |   1081 | // //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
 | 
| marci@281 |   1082 | // //       for(typename std::list<Node>::const_iterator i=S.begin(); 
 | 
| marci@281 |   1083 | // // 	  i!=S.end(); ++i) {
 | 
| marci@281 |   1084 | // // 	bfs.pushAndSetReached(*i);
 | 
| marci@281 |   1085 | // //       }
 | 
| marci@281 |   1086 | // //       //bfs.pushAndSetReached(s);
 | 
| marci@281 |   1087 | 	
 | 
| marci@281 |   1088 | // //       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
 | 
| marci@281 |   1089 | // //       //filled up with invalid iterators
 | 
| marci@281 |   1090 |       
 | 
| marci@281 |   1091 | // //       typename AugGraph::NodeMap<Number> free(res_graph);
 | 
| marci@281 |   1092 | 	
 | 
| marci@281 |   1093 | // //       //searching for augmenting path
 | 
| marci@281 |   1094 | // //       while ( !bfs.finished() ) { 
 | 
| marci@281 |   1095 | // // 	AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
 | 
| marci@281 |   1096 | // // 	if (e.valid() && bfs.isBNodeNewlyReached()) {
 | 
| marci@281 |   1097 | // // 	  Node v=res_graph.tail(e);
 | 
| marci@281 |   1098 | // // 	  Node w=res_graph.head(e);
 | 
| marci@281 |   1099 | // // 	  pred.set(w, e);
 | 
| marci@281 |   1100 | // // 	  if (pred.get(v).valid()) {
 | 
| marci@281 |   1101 | // // 	    free.set(w, std::min(free.get(v), e.free()));
 | 
| marci@281 |   1102 | // // 	  } else {
 | 
| marci@281 |   1103 | // // 	    free.set(w, e.free()); 
 | 
| marci@281 |   1104 | // // 	  }
 | 
| marci@281 |   1105 | // // 	  if (TMap.get(res_graph.head(e))) { 
 | 
| marci@281 |   1106 | // // 	    _augment=true; 
 | 
| marci@281 |   1107 | // // 	    reached_t_node=res_graph.head(e);
 | 
| marci@281 |   1108 | // // 	    break; 
 | 
| marci@281 |   1109 | // // 	  }
 | 
| marci@281 |   1110 | // // 	}
 | 
| marci@281 |   1111 | 	
 | 
| marci@281 |   1112 | // // 	++bfs;
 | 
| marci@281 |   1113 | // //       } //end of searching augmenting path
 | 
| marci@281 |   1114 | 
 | 
| marci@281 |   1115 | // //       if (_augment) {
 | 
| marci@281 |   1116 | // // 	Node n=reached_t_node;
 | 
| marci@281 |   1117 | // // 	Number augment_value=free.get(reached_t_node);
 | 
| marci@281 |   1118 | // // 	while (pred.get(n).valid()) { 
 | 
| marci@281 |   1119 | // // 	  AugEdge e=pred.get(n);
 | 
| marci@281 |   1120 | // // 	  e.augment(augment_value); 
 | 
| marci@281 |   1121 | // // 	  n=res_graph.tail(e);
 | 
| marci@281 |   1122 | // // 	}
 | 
| marci@281 |   1123 | // //       }
 | 
| marci@281 |   1124 | 
 | 
| marci@281 |   1125 | // //       return _augment;
 | 
| marci@281 |   1126 | // //     }
 | 
| marci@281 |   1127 | // //     void run() {
 | 
| marci@281 |   1128 | // //       while (augment()) { } 
 | 
| marci@281 |   1129 | // //     }
 | 
| marci@281 |   1130 | // //     Number flowValue() { 
 | 
| marci@281 |   1131 | // //       Number a=0;
 | 
| marci@281 |   1132 | // //       for(typename std::list<Node>::const_iterator i=S.begin(); 
 | 
| marci@281 |   1133 | // // 	  i!=S.end(); ++i) { 
 | 
| marci@281 |   1134 | // // 	for(OutEdgeIt e=G.template first<OutEdgeIt>(*i); e.valid(); ++e) {
 | 
| marci@281 |   1135 | // // 	  a+=flow.get(e);
 | 
| marci@281 |   1136 | // // 	}
 | 
| marci@281 |   1137 | // // 	for(InEdgeIt e=G.template first<InEdgeIt>(*i); e.valid(); ++e) {
 | 
| marci@281 |   1138 | // // 	  a-=flow.get(e);
 | 
| marci@281 |   1139 | // // 	}
 | 
| marci@281 |   1140 | // //       }
 | 
| marci@281 |   1141 | // //       return a;
 | 
| marci@281 |   1142 | // //     }
 | 
| marci@281 |   1143 | // //   };
 | 
| marci@281 |   1144 | 
 | 
| marci@281 |   1145 | 
 | 
| marci@281 |   1146 | } // namespace hugo
 | 
| marci@281 |   1147 | 
 | 
| marci@281 |   1148 | #endif //HUGO_EDMONDS_KARP_H
 |