src/work/marci/oldies/edmonds_karp.h
author athos
Tue, 11 May 2004 16:38:17 +0000
changeset 611 83530dad618a
child 921 818510fa3d99
permissions -rw-r--r--
Some modifications and another testfile.
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