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