// -*- c++ -*- #ifndef HUGO_EDMONDS_KARP_H #define HUGO_EDMONDS_KARP_H #include #include #include #include #include #include #include namespace hugo { // template // class ResGraph { // public: // typedef typename Graph::Node Node; // typedef typename Graph::NodeIt NodeIt; // private: // typedef typename Graph::SymEdgeIt OldSymEdgeIt; // const Graph& G; // const CapacityMap& capacity; // FlowMap& flow; // public: // ResGraph(const Graph& _G, const CapacityMap& _capacity, FlowMap& _flow) : // G(_G), capacity(_capacity), flow(_flow) { } // class Edge; // class OutEdgeIt; // friend class Edge; // friend class OutEdgeIt; // class Edge { // friend class ResGraph; // protected: // const ResGraph* resG; // OldSymEdgeIt sym; // public: // Edge() { } // //Edge(const Edge& e) : resG(e.resG), sym(e.sym) { } // Number free() const { // if (resG->G.aNode(sym)==resG->G.tail(sym)) { // return (resG->capacity.get(sym)-resG->flow.get(sym)); // } else { // return (resG->flow.get(sym)); // } // } // bool valid() const { return sym.valid(); } // void augment(Number a) const { // if (resG->G.aNode(sym)==resG->G.tail(sym)) { // resG->flow.set(sym, resG->flow.get(sym)+a); // //resG->flow[sym]+=a; // } else { // resG->flow.set(sym, resG->flow.get(sym)-a); // //resG->flow[sym]-=a; // } // } // }; // class OutEdgeIt : public Edge { // friend class ResGraph; // public: // OutEdgeIt() { } // //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; } // private: // OutEdgeIt(const ResGraph& _resG, Node v) { // resG=&_resG; // sym=resG->G.template first(v); // while( sym.valid() && !(free()>0) ) { ++sym; } // } // public: // OutEdgeIt& operator++() { // ++sym; // while( sym.valid() && !(free()>0) ) { ++sym; } // return *this; // } // }; // void /*getF*/first(OutEdgeIt& e, Node v) const { // e=OutEdgeIt(*this, v); // } // void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); } // template< typename It > // It first() const { // It e; // /*getF*/first(e); // return e; // } // template< typename It > // It first(Node v) const { // It e; // /*getF*/first(e, v); // return e; // } // Node tail(Edge e) const { return G.aNode(e.sym); } // Node head(Edge e) const { return G.bNode(e.sym); } // Node aNode(OutEdgeIt e) const { return G.aNode(e.sym); } // Node bNode(OutEdgeIt e) const { return G.bNode(e.sym); } // int id(Node v) const { return G.id(v); } // template // class NodeMap { // typename Graph::NodeMap node_map; // public: // NodeMap(const ResGraph& _G) : node_map(_G.G) { } // NodeMap(const ResGraph& _G, S a) : node_map(_G.G, a) { } // void set(Node nit, S a) { node_map.set(nit, a); } // S get(Node nit) const { return node_map.get(nit); } // S& operator[](Node nit) { return node_map[nit]; } // const S& operator[](Node nit) const { return node_map[nit]; } // }; // }; // template // class ResGraph2 { // public: // typedef typename Graph::Node Node; // typedef typename Graph::NodeIt NodeIt; // private: // //typedef typename Graph::SymEdgeIt OldSymEdgeIt; // typedef typename Graph::OutEdgeIt OldOutEdgeIt; // typedef typename Graph::InEdgeIt OldInEdgeIt; // const Graph& G; // FlowMap& flow; // const CapacityMap& capacity; // public: // ResGraph2(const Graph& _G, FlowMap& _flow, // const CapacityMap& _capacity) : // G(_G), flow(_flow), capacity(_capacity) { } // class Edge; // class OutEdgeIt; // friend class Edge; // friend class OutEdgeIt; // class Edge { // friend class ResGraph2; // protected: // const ResGraph2* resG; // //OldSymEdgeIt sym; // OldOutEdgeIt out; // OldInEdgeIt in; // bool out_or_in; //true, iff out // public: // Edge() : out_or_in(true) { } // Number free() const { // if (out_or_in) { // return (resG->capacity.get(out)-resG->flow.get(out)); // } else { // return (resG->flow.get(in)); // } // } // bool valid() const { // return out_or_in && out.valid() || in.valid(); } // void augment(Number a) const { // if (out_or_in) { // resG->flow.set(out, resG->flow.get(out)+a); // } else { // resG->flow.set(in, resG->flow.get(in)-a); // } // } // }; // class OutEdgeIt : public Edge { // friend class ResGraph2; // public: // OutEdgeIt() { } // private: // OutEdgeIt(const ResGraph2& _resG, Node v) { // resG=&_resG; // out=resG->G.template first(v); // while( out.valid() && !(free()>0) ) { ++out; } // if (!out.valid()) { // out_or_in=0; // in=resG->G.template first(v); // while( in.valid() && !(free()>0) ) { ++in; } // } // } // public: // OutEdgeIt& operator++() { // if (out_or_in) { // Node v=resG->G.aNode(out); // ++out; // while( out.valid() && !(free()>0) ) { ++out; } // if (!out.valid()) { // out_or_in=0; // in=resG->G.template first(v); // while( in.valid() && !(free()>0) ) { ++in; } // } // } else { // ++in; // while( in.valid() && !(free()>0) ) { ++in; } // } // return *this; // } // }; // void /*getF*/first(OutEdgeIt& e, Node v) const { // e=OutEdgeIt(*this, v); // } // void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); } // template< typename It > // It first() const { // It e; // /*getF*/first(e); // return e; // } // template< typename It > // It first(Node v) const { // It e; // /*getF*/first(e, v); // return e; // } // Node tail(Edge e) const { // return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); } // Node head(Edge e) const { // return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); } // Node aNode(OutEdgeIt e) const { // return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); } // Node bNode(OutEdgeIt e) const { // return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); } // int id(Node v) const { return G.id(v); } // template // class NodeMap { // typename Graph::NodeMap node_map; // public: // NodeMap(const ResGraph2& _G) : node_map(_G.G) { } // NodeMap(const ResGraph2& _G, S a) : node_map(_G.G, a) { } // void set(Node nit, S a) { node_map.set(nit, a); } // S get(Node nit) const { return node_map.get(nit); } // }; // }; template class MaxFlow { protected: typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; typedef typename Graph::EdgeIt EdgeIt; typedef typename Graph::OutEdgeIt OutEdgeIt; typedef typename Graph::InEdgeIt InEdgeIt; const Graph* g; Node s; Node t; const CapacityMap* capacity; FlowMap* flow; typedef ResGraphWrapper ResGW; typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt; typedef typename ResGW::Edge ResGWEdge; public: MaxFlow(const Graph& _g, Node _s, Node _t, const CapacityMap& _capacity, FlowMap& _flow) : g(&_g), s(_s), t(_t), capacity(&_capacity), flow(&_flow) { } bool augmentOnShortestPath() { ResGW res_graph(*g, *capacity, *flow); bool _augment=false; BfsIterator< ResGW, typename ResGW::template NodeMap > bfs(res_graph); bfs.pushAndSetReached(s); typename ResGW::template NodeMap pred(res_graph); pred.set(s, INVALID); typename ResGW::template NodeMap free(res_graph); //searching for augmenting path while ( !bfs.finished() ) { ResGWOutEdgeIt e=bfs; if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { Node v=res_graph.tail(e); Node w=res_graph.head(e); pred.set(w, e); if (res_graph.valid(pred[v])) { free.set(w, std::min(free[v], res_graph.resCap(e))); } else { free.set(w, res_graph.resCap(e)); } if (res_graph.head(e)==t) { _augment=true; break; } } ++bfs; } //end of searching augmenting path if (_augment) { Node n=t; Number augment_value=free[t]; while (res_graph.valid(pred[n])) { ResGWEdge e=pred[n]; res_graph.augment(e, augment_value); n=res_graph.tail(e); } } return _augment; } template class DistanceMap { protected: const MapGraphWrapper* g; typename MapGraphWrapper::template NodeMap dist; public: DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { } void set(const typename MapGraphWrapper::Node& n, int a) { dist.set(n, a); } int operator[](const typename MapGraphWrapper::Node& n) { return dist[n]; } // int get(const typename MapGraphWrapper::Node& n) const { // return dist[n]; } // bool get(const typename MapGraphWrapper::Edge& e) const { // return (dist.get(g->tail(e))head(e))); } bool operator[](const typename MapGraphWrapper::Edge& e) const { return (dist[g->tail(e)]head(e)]); } }; template bool augmentOnBlockingFlow() { typedef MutableGraph MG; bool _augment=false; ResGW res_graph(*g, *capacity, *flow); BfsIterator< ResGW, typename ResGW::template NodeMap > bfs(res_graph); bfs.pushAndSetReached(s); //typename ResGW::NodeMap dist(res_graph); //filled up with 0's DistanceMap dist(res_graph); while ( !bfs.finished() ) { ResGWOutEdgeIt e=bfs; if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1); } ++bfs; } //computing distances from s in the residual graph MG F; ConstMap true_map(true); typedef SubGraphWrapper, DistanceMap > FilterResGW; FilterResGW filter_res_graph(res_graph, true_map, dist); typename ResGW::template NodeMap res_graph_to_F(res_graph); { typename ResGW::NodeIt n; for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) { res_graph_to_F.set(n, F.addNode()); } } typename MG::Node sF=res_graph_to_F[s]; typename MG::Node tF=res_graph_to_F[t]; typename MG::template EdgeMap original_edge(F); typename MG::template EdgeMap residual_capacity(F); //Making F to the graph containing the edges of the residual graph //which are in some shortest paths { typename FilterResGW::EdgeIt e; for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) { //if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) { typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]); original_edge.update(); original_edge.set(f, e); residual_capacity.update(); residual_capacity.set(f, res_graph.resCap(e)); //} } } bool __augment=true; while (__augment) { __augment=false; //computing blocking flow with dfs DfsIterator< MG, typename MG::template NodeMap > dfs(F); typename MG::template NodeMap pred(F); pred.set(sF, INVALID); //invalid iterators for sources typename MG::template NodeMap free(F); dfs.pushAndSetReached(sF); while (!dfs.finished()) { ++dfs; if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) { if (dfs.isBNodeNewlyReached()) { typename MG::Node v=F.aNode(dfs); typename MG::Node w=F.bNode(dfs); pred.set(w, dfs); if (F.valid(pred[v])) { free.set(w, std::min(free[v], residual_capacity[dfs])); } else { free.set(w, residual_capacity[dfs]); } if (w==tF) { __augment=true; _augment=true; break; } } else { F.erase(/*typename MG::OutEdgeIt*/(dfs)); } } } if (__augment) { typename MG::Node n=tF; Number augment_value=free[tF]; while (F.valid(pred[n])) { typename MG::Edge e=pred[n]; res_graph.augment(original_edge[e], augment_value); n=F.tail(e); if (residual_capacity[e]==augment_value) F.erase(e); else residual_capacity.set(e, residual_capacity[e]-augment_value); } } } return _augment; } template bool augmentOnBlockingFlow1() { typedef MutableGraph MG; bool _augment=false; ResGW res_graph(*g, *capacity, *flow); //bfs for distances on the residual graph BfsIterator< ResGW, typename ResGW::template NodeMap > bfs(res_graph); bfs.pushAndSetReached(s); typename ResGW::template NodeMap dist(res_graph); //filled up with 0's //F will contain the physical copy of the residual graph //with the set of edges which are on shortest paths MG F; typename ResGW::template NodeMap res_graph_to_F(res_graph); { typename ResGW::NodeIt n; for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) { res_graph_to_F.set(n, F.addNode()); } } typename MG::Node sF=res_graph_to_F[s]; typename MG::Node tF=res_graph_to_F[t]; typename MG::template EdgeMap original_edge(F); typename MG::template EdgeMap residual_capacity(F); while ( !bfs.finished() ) { ResGWOutEdgeIt e=bfs; if (res_graph.valid(e)) { if (bfs.isBNodeNewlyReached()) { dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1); typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]); original_edge.update(); original_edge.set(f, e); residual_capacity.update(); residual_capacity.set(f, res_graph.resCap(e)); } else { if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) { typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]); original_edge.update(); original_edge.set(f, e); residual_capacity.update(); residual_capacity.set(f, res_graph.resCap(e)); } } } ++bfs; } //computing distances from s in the residual graph bool __augment=true; while (__augment) { __augment=false; //computing blocking flow with dfs DfsIterator< MG, typename MG::template NodeMap > dfs(F); typename MG::template NodeMap pred(F); pred.set(sF, INVALID); //invalid iterators for sources typename MG::template NodeMap free(F); dfs.pushAndSetReached(sF); while (!dfs.finished()) { ++dfs; if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) { if (dfs.isBNodeNewlyReached()) { typename MG::Node v=F.aNode(dfs); typename MG::Node w=F.bNode(dfs); pred.set(w, dfs); if (F.valid(pred[v])) { free.set(w, std::min(free[v], residual_capacity[dfs])); } else { free.set(w, residual_capacity[dfs]); } if (w==tF) { __augment=true; _augment=true; break; } } else { F.erase(/*typename MG::OutEdgeIt*/(dfs)); } } } if (__augment) { typename MG::Node n=tF; Number augment_value=free[tF]; while (F.valid(pred[n])) { typename MG::Edge e=pred[n]; res_graph.augment(original_edge[e], augment_value); n=F.tail(e); if (residual_capacity[e]==augment_value) F.erase(e); else residual_capacity.set(e, residual_capacity[e]-augment_value); } } } return _augment; } bool augmentOnBlockingFlow2() { bool _augment=false; ResGW res_graph(*g, *capacity, *flow); BfsIterator< ResGW, typename ResGW::template NodeMap > bfs(res_graph); bfs.pushAndSetReached(s); DistanceMap dist(res_graph); while ( !bfs.finished() ) { ResGWOutEdgeIt e=bfs; if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1); } ++bfs; } //computing distances from s in the residual graph //Subgraph containing the edges on some shortest paths ConstMap true_map(true); typedef SubGraphWrapper, DistanceMap > FilterResGW; FilterResGW filter_res_graph(res_graph, true_map, dist); //Subgraph, which is able to delete edges which are already //met by the dfs typename FilterResGW::template NodeMap first_out_edges(filter_res_graph); typename FilterResGW::NodeIt v; for(filter_res_graph.first(v); filter_res_graph.valid(v); filter_res_graph.next(v)) { typename FilterResGW::OutEdgeIt e; filter_res_graph.first(e, v); first_out_edges.set(v, e); } typedef ErasingFirstGraphWrapper > ErasingResGW; ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges); bool __augment=true; while (__augment) { __augment=false; //computing blocking flow with dfs DfsIterator< ErasingResGW, typename ErasingResGW::template NodeMap > dfs(erasing_res_graph); typename ErasingResGW:: template NodeMap pred(erasing_res_graph); pred.set(s, INVALID); //invalid iterators for sources typename ErasingResGW::template NodeMap free1(erasing_res_graph); dfs.pushAndSetReached( typename ErasingResGW::Node( typename FilterResGW::Node( typename ResGW::Node(s) ) ) ); while (!dfs.finished()) { ++dfs; if (erasing_res_graph.valid( typename ErasingResGW::OutEdgeIt(dfs))) { if (dfs.isBNodeNewlyReached()) { typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs); typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs); pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs)); if (erasing_res_graph.valid(pred[v])) { free1.set(w, std::min(free1[v], res_graph.resCap( typename ErasingResGW::OutEdgeIt(dfs)))); } else { free1.set(w, res_graph.resCap( typename ErasingResGW::OutEdgeIt(dfs))); } if (w==t) { __augment=true; _augment=true; break; } } else { erasing_res_graph.erase(dfs); } } } if (__augment) { typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t)); // typename ResGW::NodeMap a(res_graph); // typename ResGW::Node b; // Number j=a[b]; // typename FilterResGW::NodeMap a1(filter_res_graph); // typename FilterResGW::Node b1; // Number j1=a1[b1]; // typename ErasingResGW::NodeMap a2(erasing_res_graph); // typename ErasingResGW::Node b2; // Number j2=a2[b2]; Number augment_value=free1[n]; while (erasing_res_graph.valid(pred[n])) { typename ErasingResGW::OutEdgeIt e=pred[n]; res_graph.augment(e, augment_value); n=erasing_res_graph.tail(e); if (res_graph.resCap(e)==0) erasing_res_graph.erase(e); } } } //while (__augment) return _augment; } void run() { //int num_of_augmentations=0; while (augmentOnShortestPath()) { //while (augmentOnBlockingFlow()) { //std::cout << ++num_of_augmentations << " "; //std::cout< void run() { //int num_of_augmentations=0; //while (augmentOnShortestPath()) { while (augmentOnBlockingFlow()) { //std::cout << ++num_of_augmentations << " "; //std::cout<first(e, s); g->valid(e); g->next(e)) { a+=(*flow)[e]; } return a; } }; // template // class MaxMatching { // public: // typedef typename Graph::Node Node; // typedef typename Graph::NodeIt NodeIt; // typedef typename Graph::Edge Edge; // typedef typename Graph::EdgeIt EdgeIt; // typedef typename Graph::OutEdgeIt OutEdgeIt; // typedef typename Graph::InEdgeIt InEdgeIt; // typedef typename Graph::NodeMap SMap; // typedef typename Graph::NodeMap TMap; // private: // const Graph* G; // SMap* S; // TMap* T; // //Node s; // //Node t; // FlowMap* flow; // const CapacityMap* capacity; // typedef ResGraphWrapper AugGraph; // typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; // typedef typename AugGraph::Edge AugEdge; // typename Graph::NodeMap used; //0 // public: // MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapacityMap& _capacity) : // G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { } // bool augmentOnShortestPath() { // AugGraph res_graph(*G, *flow, *capacity); // bool _augment=false; // typedef typename AugGraph::NodeMap ReachedMap; // BfsIterator< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph); // typename AugGraph::NodeMap pred(res_graph); // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { // if ((S->get(s)) && (used.get(s)<1) ) { // //Number u=0; // //for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) // //u+=flow->get(e); // //if (u<1) { // bfs.pushAndSetReached(s); // pred.set(s, AugEdge(INVALID)); // //} // } // } // typename AugGraph::NodeMap free(res_graph); // Node n; // //searching for augmenting path // while ( !bfs.finished() ) { // AugOutEdgeIt e=bfs; // if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { // Node v=res_graph.tail(e); // Node w=res_graph.head(e); // pred.set(w, e); // if (res_graph.valid(pred.get(v))) { // free.set(w, std::min(free.get(v), res_graph.free(e))); // } else { // free.set(w, res_graph.free(e)); // } // n=res_graph.head(e); // if (T->get(n) && (used.get(n)<1) ) { // //Number u=0; // //for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) // //u+=flow->get(f); // //if (u<1) { // _augment=true; // break; // //} // } // } // ++bfs; // } //end of searching augmenting path // if (_augment) { // //Node n=t; // used.set(n, 1); //mind2 vegen jav // Number augment_value=free.get(n); // while (res_graph.valid(pred.get(n))) { // AugEdge e=pred.get(n); // res_graph.augment(e, augment_value); // n=res_graph.tail(e); // } // used.set(n, 1); //mind2 vegen jav // } // return _augment; // } // // template bool augmentOnBlockingFlow() { // // bool _augment=false; // // AugGraph res_graph(*G, *flow, *capacity); // // typedef typename AugGraph::NodeMap ReachedMap; // // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); // // //typename AugGraph::NodeMap pred(res_graph); // // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { // // if (S->get(s)) { // // Number u=0; // // for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) // // u+=flow->get(e); // // if (u<1) { // // bfs.pushAndSetReached(s); // // //pred.set(s, AugEdge(INVALID)); // // } // // } // // } // // //bfs.pushAndSetReached(s); // // typename AugGraph::NodeMap dist(res_graph); //filled up with 0's // // while ( !bfs.finished() ) { // // AugOutEdgeIt e=bfs; // // if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { // // dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); // // } // // ++bfs; // // } //computing distances from s in the residual graph // // MutableGraph F; // // typename AugGraph::NodeMap // // res_graph_to_F(res_graph); // // for(typename AugGraph::NodeIt n=res_graph.template first(); res_graph.valid(n); res_graph.next(n)) { // // res_graph_to_F.set(n, F.addNode()); // // } // // typename MutableGraph::Node sF=res_graph_to_F.get(s); // // typename MutableGraph::Node tF=res_graph_to_F.get(t); // // typename MutableGraph::EdgeMap original_edge(F); // // typename MutableGraph::EdgeMap residual_capacity(F); // // //Making F to the graph containing the edges of the residual graph // // //which are in some shortest paths // // for(typename AugGraph::EdgeIt e=res_graph.template first(); res_graph.valid(e); res_graph.next(e)) { // // if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) { // // typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e))); // // original_edge.update(); // // original_edge.set(f, e); // // residual_capacity.update(); // // residual_capacity.set(f, res_graph.free(e)); // // } // // } // // bool __augment=true; // // while (__augment) { // // __augment=false; // // //computing blocking flow with dfs // // typedef typename MutableGraph::NodeMap BlockingReachedMap; // // DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F); // // typename MutableGraph::NodeMap pred(F); // // pred.set(sF, typename MutableGraph::Edge(INVALID)); // // //invalid iterators for sources // // typename MutableGraph::NodeMap free(F); // // dfs.pushAndSetReached(sF); // // while (!dfs.finished()) { // // ++dfs; // // if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) { // // if (dfs.isBNodeNewlyReached()) { // // typename MutableGraph::Node v=F.aNode(dfs); // // typename MutableGraph::Node w=F.bNode(dfs); // // pred.set(w, dfs); // // if (F.valid(pred.get(v))) { // // free.set(w, std::min(free.get(v), residual_capacity.get(dfs))); // // } else { // // free.set(w, residual_capacity.get(dfs)); // // } // // if (w==tF) { // // __augment=true; // // _augment=true; // // break; // // } // // } else { // // F.erase(typename MutableGraph::OutEdgeIt(dfs)); // // } // // } // // } // // if (__augment) { // // typename MutableGraph::Node n=tF; // // Number augment_value=free.get(tF); // // while (F.valid(pred.get(n))) { // // typename MutableGraph::Edge e=pred.get(n); // // res_graph.augment(original_edge.get(e), augment_value); // // n=F.tail(e); // // if (residual_capacity.get(e)==augment_value) // // F.erase(e); // // else // // residual_capacity.set(e, residual_capacity.get(e)-augment_value); // // } // // } // // } // // return _augment; // // } // bool augmentOnBlockingFlow2() { // bool _augment=false; // //typedef ErasingResGraphWrapper EAugGraph; // typedef FilterGraphWrapper< ErasingResGraphWrapper > EAugGraph; // typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt; // typedef typename EAugGraph::Edge EAugEdge; // EAugGraph res_graph(*G, *flow, *capacity); // //typedef typename EAugGraph::NodeMap ReachedMap; // BfsIterator< // ErasingResGraphWrapper, // /*typename ErasingResGraphWrapper::OutEdgeIt,*/ // ErasingResGraphWrapper::NodeMap > bfs(res_graph); // //typename AugGraph::NodeMap pred(res_graph); // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { // if (S->get(s)) { // Number u=0; // for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) // u+=flow->get(e); // if (u<1) { // bfs.pushAndSetReached(s); // //pred.set(s, AugEdge(INVALID)); // } // } // } // //bfs.pushAndSetReached(s); // typename ErasingResGraphWrapper:: // NodeMap& dist=res_graph.dist; // while ( !bfs.finished() ) { // typename ErasingResGraphWrapper::OutEdgeIt e=bfs; // if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { // dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); // } // ++bfs; // } //computing distances from s in the residual graph // bool __augment=true; // while (__augment) { // __augment=false; // //computing blocking flow with dfs // typedef typename EAugGraph::NodeMap BlockingReachedMap; // DfsIterator< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > // dfs(res_graph); // typename EAugGraph::NodeMap pred(res_graph, INVALID); // //pred.set(s, EAugEdge(INVALID)); // //invalid iterators for sources // typename EAugGraph::NodeMap free(res_graph); // //typename AugGraph::NodeMap pred(res_graph); // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { // if (S->get(s)) { // Number u=0; // for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) // u+=flow->get(e); // if (u<1) { // dfs.pushAndSetReached(s); // //pred.set(s, AugEdge(INVALID)); // } // } // } // //dfs.pushAndSetReached(s); // typename EAugGraph::Node n; // while (!dfs.finished()) { // ++dfs; // if (res_graph.valid(EAugOutEdgeIt(dfs))) { // if (dfs.isBNodeNewlyReached()) { // typename EAugGraph::Node v=res_graph.aNode(dfs); // typename EAugGraph::Node w=res_graph.bNode(dfs); // pred.set(w, EAugOutEdgeIt(dfs)); // if (res_graph.valid(pred.get(v))) { // free.set(w, std::min(free.get(v), res_graph.free(dfs))); // } else { // free.set(w, res_graph.free(dfs)); // } // n=w; // if (T->get(w)) { // Number u=0; // for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) // u+=flow->get(f); // if (u<1) { // __augment=true; // _augment=true; // break; // } // } // } else { // res_graph.erase(dfs); // } // } // } // if (__augment) { // // typename EAugGraph::Node n=t; // Number augment_value=free.get(n); // while (res_graph.valid(pred.get(n))) { // EAugEdge e=pred.get(n); // res_graph.augment(e, augment_value); // n=res_graph.tail(e); // if (res_graph.free(e)==0) // res_graph.erase(e); // } // } // } // return _augment; // } // void run() { // //int num_of_augmentations=0; // while (augmentOnShortestPath()) { // //while (augmentOnBlockingFlow()) { // //std::cout << ++num_of_augmentations << " "; // //std::cout< void run() { // // //int num_of_augmentations=0; // // //while (augmentOnShortestPath()) { // // while (augmentOnBlockingFlow()) { // // //std::cout << ++num_of_augmentations << " "; // // //std::cout</*getF*/first(e); G->valid(e); G->next(e)) { // a+=flow->get(e); // } // return a; // } // }; // // template // // class MaxFlow2 { // // public: // // typedef typename Graph::Node Node; // // typedef typename Graph::Edge Edge; // // typedef typename Graph::EdgeIt EdgeIt; // // typedef typename Graph::OutEdgeIt OutEdgeIt; // // typedef typename Graph::InEdgeIt InEdgeIt; // // private: // // const Graph& G; // // std::list& S; // // std::list& T; // // FlowMap& flow; // // const CapacityMap& capacity; // // typedef ResGraphWrapper AugGraph; // // typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; // // typedef typename AugGraph::Edge AugEdge; // // typename Graph::NodeMap SMap; // // typename Graph::NodeMap TMap; // // public: // // MaxFlow2(const Graph& _G, std::list& _S, std::list& _T, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { // // for(typename std::list::const_iterator i=S.begin(); // // i!=S.end(); ++i) { // // SMap.set(*i, true); // // } // // for (typename std::list::const_iterator i=T.begin(); // // i!=T.end(); ++i) { // // TMap.set(*i, true); // // } // // } // // bool augment() { // // AugGraph res_graph(G, flow, capacity); // // bool _augment=false; // // Node reached_t_node; // // typedef typename AugGraph::NodeMap ReachedMap; // // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); // // for(typename std::list::const_iterator i=S.begin(); // // i!=S.end(); ++i) { // // bfs.pushAndSetReached(*i); // // } // // //bfs.pushAndSetReached(s); // // typename AugGraph::NodeMap pred(res_graph); // // //filled up with invalid iterators // // typename AugGraph::NodeMap free(res_graph); // // //searching for augmenting path // // while ( !bfs.finished() ) { // // AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs); // // if (e.valid() && bfs.isBNodeNewlyReached()) { // // Node v=res_graph.tail(e); // // Node w=res_graph.head(e); // // pred.set(w, e); // // if (pred.get(v).valid()) { // // free.set(w, std::min(free.get(v), e.free())); // // } else { // // free.set(w, e.free()); // // } // // if (TMap.get(res_graph.head(e))) { // // _augment=true; // // reached_t_node=res_graph.head(e); // // break; // // } // // } // // ++bfs; // // } //end of searching augmenting path // // if (_augment) { // // Node n=reached_t_node; // // Number augment_value=free.get(reached_t_node); // // while (pred.get(n).valid()) { // // AugEdge e=pred.get(n); // // e.augment(augment_value); // // n=res_graph.tail(e); // // } // // } // // return _augment; // // } // // void run() { // // while (augment()) { } // // } // // Number flowValue() { // // Number a=0; // // for(typename std::list::const_iterator i=S.begin(); // // i!=S.end(); ++i) { // // for(OutEdgeIt e=G.template first(*i); e.valid(); ++e) { // // a+=flow.get(e); // // } // // for(InEdgeIt e=G.template first(*i); e.valid(); ++e) { // // a-=flow.get(e); // // } // // } // // return a; // // } // // }; } // namespace hugo #endif //HUGO_EDMONDS_KARP_H