5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)).
10 void run() : runs the algorithm
12 The following functions should be used after run() was already run.
14 T maxflow() : returns the value of a maximum flow
16 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
18 Graph::EdgeMap<T> allflow() : returns the fixed maximum flow x
20 Graph::NodeMap<bool> mincut() : returns a
21 characteristic vector of a minimum cut. (An empty level
22 in the algorithm gives a minimum cut.)
25 #ifndef PREFLOW_PUSH_HL_H
26 #define PREFLOW_PUSH_HL_H
28 //#include <algorithm>
32 #include <reverse_bfs.h>
36 template <typename Graph, typename T>
37 class preflow_push_hl {
39 typedef typename Graph::NodeIt NodeIt;
40 typedef typename Graph::EdgeIt EdgeIt;
41 typedef typename Graph::EachNodeIt EachNodeIt;
42 typedef typename Graph::OutEdgeIt OutEdgeIt;
43 typedef typename Graph::InEdgeIt InEdgeIt;
48 typename Graph::EdgeMap<T> flow;
49 typename Graph::EdgeMap<T> capacity;
51 typename Graph::NodeMap<bool> mincutvector;
55 preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t,
56 typename Graph::EdgeMap<T>& _capacity) :
57 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity),
58 mincutvector(_G, true) { }
62 The run() function runs the highest label preflow-push,
63 running time: O(n^2\sqrt(m))
67 typename Graph::NodeMap<int> level(G);
68 typename Graph::NodeMap<T> excess(G);
73 b is a bound on the highest level of an active node.
74 In the beginning it is at most n-2.
77 std::vector<int> numb(n); //The number of nodes on level i < n.
78 std::vector<std::stack<NodeIt> > stack(2*n-1);
79 //Stack of the active nodes in level i.
82 /*Reverse_bfs from t, to find the starting level.*/
83 reverse_bfs<Graph> bfs(G, t);
85 for(EachNodeIt v=G.template first<EachNodeIt>(); v.valid(); ++v)
95 /* Starting flow. It is everywhere 0 at the moment. */
96 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
98 if ( capacity.get(e) > 0 ) {
101 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
102 flow.set(e, capacity.get(e));
103 excess.set(w, excess.get(w)+capacity.get(e));
115 Push/relabel on the highest level active nodes.
118 /*While there exists an active node.*/
121 /*We decrease the bound if there is no active node of level b.*/
122 if (stack[b].empty()) {
126 NodeIt w=stack[b].top(); //w is a highest label active node.
129 int newlevel=2*n-2; //In newlevel we bound the next level of w.
131 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
133 if ( flow.get(e) < capacity.get(e) ) {
134 /*e is an edge of the residual graph */
136 NodeIt v=G.head(e); /*e is the edge wv.*/
138 if( level.get(w) == level.get(v)+1 ) {
139 /*Push is allowed now*/
141 if ( excess.get(v)==0 && v != s && v !=t ) stack[level.get(v)].push(v);
142 /*v becomes active.*/
144 if ( capacity.get(e)-flow.get(e) > excess.get(w) ) {
145 /*A nonsaturating push.*/
147 flow.set(e, flow.get(e)+excess.get(w));
148 excess.set(v, excess.get(v)+excess.get(w));
153 /*A saturating push.*/
155 excess.set(v, excess.get(v)+capacity.get(e)-flow.get(e));
156 excess.set(w, excess.get(w)-capacity.get(e)+flow.get(e));
157 flow.set(e, capacity.get(e));
158 if ( excess.get(w)==0 ) break;
159 /*If w is not active any more, then we go on to the next node.*/
163 newlevel = newlevel < level.get(v) ? newlevel : level.get(v);
166 } //if the out edge wv is in the res graph
171 if ( excess.get(w) > 0 ) {
173 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
174 NodeIt v=G.tail(e); /*e is the edge vw.*/
176 if( flow.get(e) > 0 ) {
177 /*e is an edge of the residual graph */
179 if( level.get(w)==level.get(v)+1 ) {
180 /*Push is allowed now*/
182 if ( excess.get(v)==0 && v != s && v !=t) stack[level.get(v)].push(v);
183 /*v becomes active.*/
185 if ( flow.get(e) > excess.get(w) ) {
186 /*A nonsaturating push.*/
188 flow.set(e, flow.get(e)-excess.get(w));
189 excess.set(v, excess.get(v)+excess.get(w));
193 /*A saturating push.*/
195 excess.set(v, excess.get(v)+flow.get(e));
196 excess.set(w, excess.get(w)-flow.get(e));
198 if ( excess.get(w)==0 ) break;
201 newlevel = newlevel < level.get(v) ? newlevel : level.get(v);
204 } //if in edge vw is in the res graph
208 } // if w still has excess after the out edge for cycle
215 if ( excess.get(w) > 0 ) {
217 int oldlevel=level.get(w);
218 level.set(w,++newlevel);
220 if ( oldlevel < n ) {
223 if ( !numb[oldlevel] ) { //If the level of w gets empty.
225 for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
226 if (level.get(v) > oldlevel && level.get(v) < n ) level.set(v,n);
228 for (int i=oldlevel+1 ; i!=n ; ++i) numb[i]=0;
229 if ( newlevel < n ) newlevel=n;
231 if ( newlevel < n ) ++numb[newlevel];
234 if ( newlevel < n ) ++numb[newlevel];
237 stack[newlevel].push(w);
242 } // if stack[b] is nonempty
247 value = excess.get(t);
258 Returns the maximum value of a flow.
268 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
271 T flowonEdge(EdgeIt e) {
278 Returns the maximum flow x found by the algorithm.
281 typename Graph::EdgeMap<T> allflow() {
288 Returns a minimum cut by using a reverse bfs from t in the residual graph.
291 typename Graph::NodeMap<bool> mincut() {
293 std::queue<NodeIt> queue;
295 mincutvector.set(t,false);
298 while (!queue.empty()) {
299 NodeIt w=queue.front();
302 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
304 if (mincutvector.get(v) && flow.get(e) < capacity.get(e) ) {
306 mincutvector.set(v, false);
310 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
312 if (mincutvector.get(v) && flow.get(e) > 0 ) {
314 mincutvector.set(v, false);