src/work/marci/oldies/edmonds_karp.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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