Dynamic Maps added.
5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)), with the felszippantos 'empty level'
7 and with the two-phase heuristic: if there is no active node of
8 level at most n, then we go into phase 1, do a bfs
9 from s, and flow the excess back to s.
11 In phase 1 we shift everything downwards by n.
13 'A' is a parameter for the empty_level heuristic
17 void run() : runs the algorithm
19 The following functions should be used after run() was already run.
21 T maxflow() : returns the value of a maximum flow
23 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
25 FlowMap allflow() : returns the fixed maximum flow x
27 void mincut(CutMap& M) : sets M to the characteristic vector of a
28 minimum cut. M should be a map of bools initialized to false.
30 void min_mincut(CutMap& M) : sets M to the characteristic vector of the
31 minimum min cut. M should be a map of bools initialized to false.
33 void max_mincut(CutMap& M) : sets M to the characteristic vector of the
34 maximum min cut. M should be a map of bools initialized to false.
49 template <typename Graph, typename T,
50 typename FlowMap=typename Graph::EdgeMap<T>, typename CapMap=typename Graph::EdgeMap<T>,
51 typename IntMap=typename Graph::NodeMap<int>, typename TMap=typename Graph::NodeMap<T> >
54 typedef typename Graph::NodeIt NodeIt;
55 typedef typename Graph::EdgeIt EdgeIt;
56 typedef typename Graph::EachNodeIt EachNodeIt;
57 typedef typename Graph::OutEdgeIt OutEdgeIt;
58 typedef typename Graph::InEdgeIt InEdgeIt;
69 preflow_hl3(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
70 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
79 b is a bound on the highest level of the stack.
80 In the beginning it is at most n-2.
86 std::vector<int> numb(n);
88 The number of nodes on level i < n. It is
89 initialized to n+1, because of the reverse_bfs-part.
90 Needed only in phase 0.
93 std::vector<std::stack<NodeIt> > stack(n);
94 //Stack of the active nodes in level i < n.
95 //We use it in both phases.
98 /*Reverse_bfs from t, to find the starting level.*/
100 std::queue<NodeIt> bfs_queue;
103 while (!bfs_queue.empty()) {
105 NodeIt v=bfs_queue.front();
107 int l=level.get(v)+1;
109 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
111 if ( level.get(w) == n ) {
123 /* Starting flow. It is everywhere 0 at the moment. */
124 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
127 if ( c == 0 ) continue;
129 if ( level.get(w) < n ) {
130 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
132 excess.set(w, excess.get(w)+c);
143 Push/relabel on the highest level active nodes.
145 /*While there exists an active node.*/
154 std::queue<NodeIt> bfs_queue;
157 while (!bfs_queue.empty()) {
159 NodeIt v=bfs_queue.front();
161 int l=level.get(v)+1;
163 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
164 if ( capacity.get(e) == flow.get(e) ) continue;
166 if ( level.get(u) == n ) {
169 if ( excess.get(u) > 0 ) stack[l].push(u);
173 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
174 if ( 0 == flow.get(e) ) continue;
176 if ( level.get(u) == n ) {
179 if ( excess.get(u) > 0 ) stack[l].push(u);
187 if ( stack[b].empty() ) --b;
190 NodeIt w=stack[b].top(); //w is a highest label active node.
192 int lev=level.get(w);
193 int exc=excess.get(w);
194 int newlevel=n; //In newlevel we bound the next level of w.
196 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
198 if ( flow.get(e) == capacity.get(e) ) continue;
202 if( lev > level.get(v) ) {
203 /*Push is allowed now*/
205 if ( excess.get(v)==0 && v !=t && v!=s )
206 stack[level.get(v)].push(v);
207 /*v becomes active.*/
209 int cap=capacity.get(e);
213 if ( remcap >= exc ) {
214 /*A nonsaturating push.*/
216 flow.set(e, flo+exc);
217 excess.set(v, excess.get(v)+exc);
222 /*A saturating push.*/
225 excess.set(v, excess.get(v)+remcap);
228 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
234 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
236 if( flow.get(e) == 0 ) continue;
240 if( lev > level.get(v) ) {
241 /*Push is allowed now*/
243 if ( excess.get(v)==0 && v !=t && v!=s )
244 stack[level.get(v)].push(v);
245 /*v becomes active.*/
250 /*A nonsaturating push.*/
252 flow.set(e, flo-exc);
253 excess.set(v, excess.get(v)+exc);
257 /*A saturating push.*/
259 excess.set(v, excess.get(v)+flo);
263 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
267 } // if w still has excess after the out edge for cycle
277 //now 'lev' is the old level of w
280 level.set(w,++newlevel);
281 stack[newlevel].push(w);
285 if ( newlevel >= n-2 || --numb[lev] == 0 ) {
289 if ( newlevel < n ) {
291 std::queue<NodeIt> bfs_queue;
294 while (!bfs_queue.empty()) {
296 NodeIt v=bfs_queue.front();
299 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
300 if ( capacity.get(e) == flow.get(e) ) continue;
302 if ( level.get(u) < n ) {
304 --numb[level.get(u)];
309 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
310 if ( 0 == flow.get(e) ) continue;
312 if ( level.get(u) < n ) {
314 --numb[level.get(u)];
323 level.set(w,++newlevel);
324 stack[newlevel].push(w);
333 } // if stack[b] is nonempty
338 value = excess.get(t);
349 Returns the maximum value of a flow.
359 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
362 T flowonedge(EdgeIt e) {
369 Returns the maximum flow x found by the algorithm.
380 Returns the minimum min cut, by a bfs from s in the residual graph.
383 template<typename CutMap>
384 void mincut(CutMap& M) {
386 std::queue<NodeIt> queue;
391 while (!queue.empty()) {
392 NodeIt w=queue.front();
395 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
397 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
403 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
405 if (!M.get(v) && flow.get(e) > 0 ) {
418 Returns the maximum min cut, by a reverse bfs
419 from t in the residual graph.
422 template<typename CutMap>
423 void max_mincut(CutMap& M) {
425 std::queue<NodeIt> queue;
430 while (!queue.empty()) {
431 NodeIt w=queue.front();
434 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
436 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
442 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
444 if (!M.get(v) && flow.get(e) > 0 ) {
451 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
459 template<typename CutMap>
460 void min_mincut(CutMap& M) {