alpar@74: // -*- mode:c++ -*- alpar@74: alpar@74: #ifndef EDMONDS_KARP_HH alpar@74: #define EDMONDS_KARP_HH alpar@74: alpar@74: #include alpar@74: alpar@74: //#include alpar@74: alpar@74: #include alpar@74: alpar@74: //#include alpar@74: alpar@74: namespace marci { alpar@74: template alpar@74: typename FlowMap::ValueType maxFlow(Graph &G, alpar@74: FlowMap &f, alpar@74: CapacityMap &c, alpar@74: typename Graph::NodeIt s, alpar@74: typename Graph::NodeIt t) alpar@74: { alpar@74: typedef typename Graph::NodeIt NodeIt; alpar@74: typedef typename Graph::EdgeIt EdgeIt; alpar@74: typedef typename Graph::EachEdgeIt EachEdgeIt; alpar@74: typedef typename Graph::OutEdgeIt OutEdgeIt; alpar@74: typedef typename Graph::InEdgeIt InEdgeIt; alpar@74: typedef typename FlowMap::ValueType T; alpar@74: alpar@74: T flow_val = 0; alpar@74: T aug_val; alpar@74: alpar@74: for(EachEdgeIt e(G);G.valid(e);G.next(e)) alpar@74: f.set(e,0); alpar@74: alpar@74: std::queue bfs_queue; alpar@74: typename Graph::NodeMap visited(G); //0: unvisited, alpar@74: //1: reached by a forward edge alpar@74: //2: reached by a backward edge alpar@74: //3: it is node s alpar@74: typename Graph::NodeMap tree(G); alpar@74: alpar@74: NodeIt gn; //FIXME: it might be too global for some people... alpar@74: alpar@74: augment: alpar@74: alpar@74: for(NodeIt n(G);G.valid(n);G.next(n)) alpar@74: visited.set(n,0); alpar@74: alpar@74: visited.set(s,3); alpar@74: alpar@74: //There must be a better way to do this: alpar@74: while(!bfs_queue.empty()) bfs_queue.pop(); alpar@74: alpar@74: bfs_queue.push(s); alpar@74: alpar@74: while(!bfs_queue.empty() && !visited.get(t)) alpar@74: { alpar@74: NodeIt n(bfs_queue.front()); alpar@74: for(OutEdgeIt e(G,n);G.valid(e);G.next(e)) alpar@74: if(f.get(e)0 && //FIXME: > alpar@74: !visited.get(G.bNode(e))) alpar@74: { alpar@74: tree.set(G.bNode(e),e); alpar@74: visited.set(G.bNode(e),2); alpar@74: } alpar@74: } alpar@74: alpar@74: if(!visited.get(t)) return flow_val; alpar@74: alpar@74: // Augmenting value computation alpar@74: aug_val = visited.get(t)==2 ? alpar@74: c.get(tree.get(t))-f.get(tree.get(t)) : f.get(tree.get(t)); alpar@74: //FIXME: I would need 'G.opposite(e,n)' alpar@74: gn = visited.get(t)==2 ? G.from(tree.get(t)) : G.to(tree.get(t)); alpar@74: while(gn!=s) if(visited.get(gn)==2) alpar@74: { alpar@74: //FIXME: nonstandars. gcc extension! alpar@74: aug_val