5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)), and with the 'empty level' heuristic.
8 'A' is a parameter for the empty_level heuristic
12 void run() : runs the algorithm
14 The following functions should be used after run() was already run.
16 T maxflow() : returns the value of a maximum flow
18 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
20 FlowMap allflow() : returns the fixed maximum flow x
22 void mincut(CutMap& M) : sets M to the characteristic vector of a
23 minimum cut. M should be a map of bools initialized to false.
25 void min_mincut(CutMap& M) : sets M to the characteristic vector of the
26 minimum min cut. M should be a map of bools initialized to false.
28 void max_mincut(CutMap& M) : sets M to the characteristic vector of the
29 maximum min cut. M should be a map of bools initialized to false.
33 #ifndef PREFLOW_PUSH_HL_H
34 #define PREFLOW_PUSH_HL_H
44 template <typename Graph, typename T,
45 typename FlowMap=typename Graph::EdgeMap<T>, typename CapMap=typename Graph::EdgeMap<T>,
46 typename IntMap=typename Graph::NodeMap<int>, typename TMap=typename Graph::NodeMap<T> >
47 class preflow_push_hl {
49 typedef typename Graph::NodeIt NodeIt;
50 typedef typename Graph::EdgeIt EdgeIt;
51 typedef typename Graph::EachNodeIt EachNodeIt;
52 typedef typename Graph::OutEdgeIt OutEdgeIt;
53 typedef typename Graph::InEdgeIt InEdgeIt;
64 preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
65 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
75 b is a bound on the highest level of an active node.
81 std::vector<int> numb(n);
83 The number of nodes on level i < n. It is
84 initialized to n+1, because of the reverse_bfs-part.
87 std::vector<std::stack<NodeIt> > stack(2*n-1);
88 //Stack of the active nodes in level i.
91 /*Reverse_bfs from t, to find the starting level.*/
93 std::queue<NodeIt> bfs_queue;
96 while (!bfs_queue.empty()) {
98 NodeIt v=bfs_queue.front();
100 int l=level.get(v)+1;
102 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
104 if ( level.get(w) == n ) {
116 /* Starting flow. It is everywhere 0 at the moment. */
117 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
119 if ( capacity.get(e) == 0 ) continue;
122 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
123 flow.set(e, capacity.get(e));
124 excess.set(w, excess.get(w)+capacity.get(e));
134 Push/relabel on the highest level active nodes.
136 /*While there exists an active node.*/
138 if ( stack[b].empty() ) {
143 NodeIt w=stack[b].top(); //w is a highest label active node.
145 int lev=level.get(w);
146 int exc=excess.get(w);
147 int newlevel=2*n-2; //In newlevel we bound the next level of w.
149 // if ( level.get(w) < n ) { //Nem tudom ez mukodik-e
150 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
152 if ( flow.get(e) == capacity.get(e) ) continue;
156 if( lev > level.get(v) ) {
157 /*Push is allowed now*/
159 if ( excess.get(v)==0 && v != s && v !=t )
160 stack[level.get(v)].push(v);
161 /*v becomes active.*/
163 int cap=capacity.get(e);
167 if ( remcap >= exc ) {
168 /*A nonsaturating push.*/
170 flow.set(e, flo+exc);
171 excess.set(v, excess.get(v)+exc);
176 /*A saturating push.*/
179 excess.set(v, excess.get(v)+remcap);
182 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
188 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
190 if( flow.get(e) == 0 ) continue;
194 if( lev > level.get(v) ) {
195 /*Push is allowed now*/
197 if ( excess.get(v)==0 && v != s && v !=t)
198 stack[level.get(v)].push(v);
199 /*v becomes active.*/
204 /*A nonsaturating push.*/
206 flow.set(e, flo-exc);
207 excess.set(v, excess.get(v)+exc);
211 /*A saturating push.*/
213 excess.set(v, excess.get(v)+flo);
217 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
221 } // if w still has excess after the out edge for cycle
233 //now 'lev' is the old level of w
234 level.set(w,++newlevel);
239 if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty.
241 for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
242 if (level.get(v) > lev && level.get(v) < n ) level.set(v,n);
244 for (int i=lev+1 ; i!=n ; ++i) numb[i]=0;
245 if ( newlevel < n ) newlevel=n;
247 if ( newlevel < n ) ++numb[newlevel];
251 stack[newlevel].push(w);
259 value = excess.get(t);
270 Returns the maximum value of a flow.
280 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
283 T flowonedge(const EdgeIt e) {
290 Returns the maximum flow x found by the algorithm.
301 Returns the minimum min cut, by a bfs from s in the residual graph.
304 template<typename CutMap>
305 void mincut(CutMap& M) {
307 std::queue<NodeIt> queue;
312 while (!queue.empty()) {
313 NodeIt w=queue.front();
316 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
318 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
324 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
326 if (!M.get(v) && flow.get(e) > 0 ) {
338 Returns the maximum min cut, by a reverse bfs
339 from t in the residual graph.
342 template<typename CutMap>
343 void max_mincut(CutMap& M) {
345 std::queue<NodeIt> queue;
350 while (!queue.empty()) {
351 NodeIt w=queue.front();
354 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
356 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
362 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
364 if (!M.get(v) && flow.get(e) > 0 ) {
371 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
379 template<typename CutMap>
380 void min_mincut(CutMap& M) {