#ifndef MARCI_MAX_FLOW_HH #define MARCI_MAX_FLOW_HH #include #include namespace marci { template class ResGraph { typedef typename Graph::NodeIt NodeIt; typedef typename Graph::EachNodeIt EachNodeIt; typedef typename Graph::SymEdgeIt OldSymEdgeIt; const Graph& G; typename Graph::EdgeMap& flow; const typename Graph::EdgeMap& capacity; public: ResGraph(const Graph& _G, typename Graph::EdgeMap& _flow, const typename Graph::EdgeMap& _capacity) : G(_G), flow(_flow), capacity(_capacity) { } class EdgeIt; class OutEdgeIt; friend class EdgeIt; friend class OutEdgeIt; class EdgeIt { friend class ResGraph; protected: const ResGraph* resG; OldSymEdgeIt sym; public: EdgeIt() { } //EdgeIt(const EdgeIt& e) : resG(e.resG), sym(e.sym) { } T 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(const T a) const { if (resG->G.aNode(sym)==resG->G.tail(sym)) { resG->flow.set(sym, resG->flow.get(sym)+a); } else { resG->flow.set(sym, resG->flow.get(sym)-a); } } }; class OutEdgeIt : public EdgeIt { friend class ResGraph; public: OutEdgeIt() { } //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; } private: OutEdgeIt(const ResGraph& _resG, const NodeIt 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 getFirst(OutEdgeIt& e, const NodeIt v) const { e=OutEdgeIt(*this, v); } void getFirst(EachNodeIt& v) const { G.getFirst(v); } template< typename It > It first() const { It e; getFirst(e); return e; } template< typename It > It first(const NodeIt v) const { It e; getFirst(e, v); return e; } NodeIt tail(const EdgeIt e) const { return G.aNode(e.sym); } NodeIt head(const EdgeIt e) const { return G.bNode(e.sym); } NodeIt aNode(const OutEdgeIt e) const { return G.aNode(e.sym); } NodeIt bNode(const OutEdgeIt e) const { return G.bNode(e.sym); } int id(const NodeIt v) const { return G.id(v); } template class NodeMap { //const ResGraph& G; typename Graph::NodeMap node_map; public: NodeMap(const ResGraph& _G) : node_map(_G.G)/*: G(_G)*/ { } NodeMap(const ResGraph& _G, const ValueType a) : node_map(_G.G, a) /*: G(_G)*/ { } void set(const NodeIt nit, const ValueType a) { node_map.set(nit, a); } ValueType get(const NodeIt nit) const { return node_map.get(nit); } }; }; template struct max_flow_type { typedef typename Graph::NodeIt NodeIt; typedef typename Graph::EdgeIt EdgeIt; typedef typename Graph::EachEdgeIt EachEdgeIt; typedef typename Graph::OutEdgeIt OutEdgeIt; typedef typename Graph::InEdgeIt InEdgeIt; const Graph& G; NodeIt s; NodeIt t; typename Graph::EdgeMap flow; const typename Graph::EdgeMap& capacity; max_flow_type(const Graph& _G, NodeIt _s, NodeIt _t, const typename Graph::EdgeMap& _capacity) : G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { } void run() { typedef ResGraph AugGraph; AugGraph res_graph(G, flow, capacity); bool augment; do { augment=false; typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; typedef typename AugGraph::EdgeIt AugEdgeIt; typedef std::queue BfsQueue; BfsQueue bfs_queue; bfs_queue.push(res_graph.template first(s)); typedef typename AugGraph::NodeMap ReachedMap; ReachedMap reached(res_graph, false); reached.set(s, true); bfs_iterator1< AugGraph, ReachedMap > res_bfs(res_graph, bfs_queue, reached); typedef typename AugGraph::NodeMap PredMap; PredMap pred(res_graph); //typename AugGraph::EdgeIt a; //invalid //a.makeInvalid(); //pred.set(s, a); typedef typename AugGraph::NodeMap FreeMap; FreeMap free(res_graph); //searching for augmenting path while ( res_bfs.valid() ) { //std::cout<<"KULSO ciklus itt jar: "<"<"<"<(); e.valid(); ++e) { std::cout<<"("<"<