8 suck gap : if there is a gap, then we put all
9 nodes reachable from the relabelled node to level n
13 The constructor runs the algorithm.
17 T maxFlow() : returns the value of a maximum flow
19 T flowOnEdge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
21 FlowMap Flow() : returns the fixed maximum flow x
23 void minCut(CutMap& M) : sets M to the characteristic vector of a
24 minimum cut. M should be a map of bools initialized to false.
26 void minMinCut(CutMap& M) : sets M to the characteristic vector of the
27 minimum min cut. M should be a map of bools initialized to false.
29 void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
30 maximum min cut. M should be a map of bools initialized to false.
41 #include <time_measure.h> //for test
45 template <typename Graph, typename T,
46 typename FlowMap=typename Graph::EdgeMap<T>,
47 typename CapMap=typename Graph::EdgeMap<T> >
50 typedef typename Graph::NodeIt NodeIt;
51 typedef typename Graph::EdgeIt EdgeIt;
52 typedef typename Graph::EachNodeIt EachNodeIt;
53 typedef typename Graph::OutEdgeIt OutEdgeIt;
54 typedef typename Graph::InEdgeIt InEdgeIt;
65 double time; //for test
67 preflow_hl3(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
68 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) {
74 b is a bound on the highest level of the stack.
75 In the beginning it is at most n-2.
78 typename Graph::NodeMap<int> level(G,n);
79 typename Graph::NodeMap<T> excess(G);
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.
85 Needed only in phase 0.
88 std::vector<std::stack<NodeIt> > stack(n);
89 //Stack of the active nodes in level i < n.
90 //We use it in both phases.
93 /*Reverse_bfs from t, to find the starting level.*/
95 std::queue<NodeIt> bfs_queue;
98 while (!bfs_queue.empty()) {
100 NodeIt v=bfs_queue.front();
102 int l=level.get(v)+1;
104 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
106 if ( level.get(w) == n ) {
118 /* Starting flow. It is everywhere 0 at the moment. */
119 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
122 if ( c == 0 ) continue;
124 if ( level.get(w) < n ) {
125 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
127 excess.set(w, excess.get(w)+c);
138 Push/relabel on the highest level active nodes.
140 /*While there exists an active node.*/
150 std::queue<NodeIt> bfs_queue;
153 while (!bfs_queue.empty()) {
155 NodeIt v=bfs_queue.front();
157 int l=level.get(v)+1;
159 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
160 if ( capacity.get(e) == flow.get(e) ) continue;
162 if ( level.get(u) == n ) {
165 if ( excess.get(u) > 0 ) stack[l].push(u);
169 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
170 if ( 0 == flow.get(e) ) continue;
172 if ( level.get(u) == n ) {
175 if ( excess.get(u) > 0 ) stack[l].push(u);
183 if ( stack[b].empty() ) --b;
186 NodeIt w=stack[b].top();
188 int lev=level.get(w);
190 int newlevel=n; //bound on the next level of w.
192 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
194 if ( flow.get(e) == capacity.get(e) ) continue;
198 if( lev > level.get(v) ) {
199 /*Push is allowed now*/
201 if ( excess.get(v)==0 && v !=t && v!=s )
202 stack[level.get(v)].push(v);
203 /*v becomes active.*/
205 T cap=capacity.get(e);
209 if ( remcap >= exc ) {
210 /*A nonsaturating push.*/
212 flow.set(e, flo+exc);
213 excess.set(v, excess.get(v)+exc);
218 /*A saturating push.*/
221 excess.set(v, excess.get(v)+remcap);
224 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
230 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
232 if( flow.get(e) == 0 ) continue;
236 if( lev > level.get(v) ) {
237 /*Push is allowed now*/
239 if ( excess.get(v)==0 && v !=t && v!=s )
240 stack[level.get(v)].push(v);
241 /*v becomes active.*/
246 /*A nonsaturating push.*/
248 flow.set(e, flo-exc);
249 excess.set(v, excess.get(v)+exc);
253 /*A saturating push.*/
255 excess.set(v, excess.get(v)+flo);
259 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
263 } // if w still has excess after the out edge for cycle
273 //now 'lev' is the old level of w
276 level.set(w,++newlevel);
277 stack[newlevel].push(w);
281 if ( newlevel >= n-2 || --numb[lev] == 0 ) {
285 if ( newlevel < n ) {
287 std::queue<NodeIt> bfs_queue;
290 while (!bfs_queue.empty()) {
292 NodeIt v=bfs_queue.front();
295 for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
296 if ( capacity.get(e) == flow.get(e) ) continue;
298 if ( level.get(u) < n ) {
300 --numb[level.get(u)];
305 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
306 if ( 0 == flow.get(e) ) continue;
308 if ( level.get(u) < n ) {
310 --numb[level.get(u)];
319 level.set(w,++newlevel);
320 stack[newlevel].push(w);
329 } // if stack[b] is nonempty
334 value = excess.get(t);
345 Returns the maximum value of a flow.
355 For the maximum flow x found by the algorithm,
356 it returns the flow value on edge e, i.e. x(e).
359 T flowOnEdge(EdgeIt e) {
366 Returns the maximum flow x found by the algorithm.
377 Returns the minimum min cut, by a bfs from s in the residual graph.
380 template<typename CutMap>
381 void minCut(CutMap& M) {
383 std::queue<NodeIt> queue;
388 while (!queue.empty()) {
389 NodeIt w=queue.front();
392 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
394 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
400 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
402 if (!M.get(v) && flow.get(e) > 0 ) {
415 Returns the maximum min cut, by a reverse bfs
416 from t in the residual graph.
419 template<typename CutMap>
420 void maxMinCut(CutMap& M) {
422 std::queue<NodeIt> queue;
427 while (!queue.empty()) {
428 NodeIt w=queue.front();
431 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
433 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
439 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
441 if (!M.get(v) && flow.get(e) > 0 ) {
448 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
456 template<typename CutMap>
457 void minMinCut(CutMap& M) {