.
5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)).
10 gap: we iterate through the nodes for finding the nodes above
11 the gap and under level n. So it is quite slow.
12 numb: we maintain the number of nodes in level i.
15 'A' is a parameter for the gap, we only upgrade the nodes to level n,
16 if the gap is under A*n.
18 The constructor runs the algorithm.
22 T maxFlow() : returns the value of a maximum flow
24 T flowOnEdge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
26 FlowMap Flow() : returns the fixed maximum flow x
28 void minCut(CutMap& M) : sets M to the characteristic vector of a
29 minimum cut. M should be a map of bools initialized to false.
31 void minMinCut(CutMap& M) : sets M to the characteristic vector of the
32 minimum min cut. M should be a map of bools initialized to false.
34 void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
35 maximum min cut. M should be a map of bools initialized to false.
50 template <typename Graph, typename T,
51 typename FlowMap=typename Graph::EdgeMap<T>,
52 typename CapMap=typename Graph::EdgeMap<T> >
55 typedef typename Graph::NodeIt NodeIt;
56 typedef typename Graph::EdgeIt EdgeIt;
57 typedef typename Graph::EachNodeIt EachNodeIt;
58 typedef typename Graph::OutEdgeIt OutEdgeIt;
59 typedef typename Graph::InEdgeIt InEdgeIt;
70 preflow_hl2(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
71 G(_G), s(_s), t(_t), flow(_G), capacity(_capacity) {
76 b is a bound on the highest level of an active node.
79 typename Graph::NodeMap<int> level(G,n);
80 typename Graph::NodeMap<T> excess(G);
82 std::vector<int> numb(n);
84 The number of nodes on level i < n. It is
85 initialized to n+1, because of the reverse_bfs-part.
88 std::vector<std::stack<NodeIt> > stack(2*n-1);
89 //Stack of the active nodes in level i.
92 /*Reverse_bfs from t, to find the starting level.*/
94 std::queue<NodeIt> bfs_queue;
97 while (!bfs_queue.empty()) {
99 NodeIt v=bfs_queue.front();
101 int l=level.get(v)+1;
103 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
105 if ( level.get(w) == n ) {
117 /* Starting flow. It is everywhere 0 at the moment. */
118 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
121 if ( c == 0 ) continue;
124 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
126 excess.set(w, excess.get(w)+c);
136 Push/relabel on the highest level active nodes.
138 /*While there exists an active node.*/
140 if ( stack[b].empty() ) {
145 NodeIt w=stack[b].top();
147 int lev=level.get(w);
149 int newlevel=2*n; //In newlevel we bound the next level of w.
151 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
153 if ( flow.get(e) == capacity.get(e) ) continue;
157 if( lev > level.get(v) ) {
158 /*Push is allowed now*/
160 if ( excess.get(v)==0 && v != s && v !=t )
161 stack[level.get(v)].push(v);
162 /*v becomes active.*/
164 T cap=capacity.get(e);
168 if ( remcap >= exc ) {
169 /*A nonsaturating push.*/
171 flow.set(e, flo+exc);
172 excess.set(v, excess.get(v)+exc);
177 /*A saturating push.*/
180 excess.set(v, excess.get(v)+remcap);
183 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
189 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
191 if( flow.get(e) == 0 ) continue;
195 if( lev > level.get(v) ) {
196 /*Push is allowed now*/
198 if ( excess.get(v)==0 && v != s && v !=t)
199 stack[level.get(v)].push(v);
200 /*v becomes active.*/
205 /*A nonsaturating push.*/
207 flow.set(e, flo-exc);
208 excess.set(v, excess.get(v)+exc);
212 /*A saturating push.*/
214 excess.set(v, excess.get(v)+flo);
218 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
222 } // if w still has excess after the out edge for cycle
234 //now 'lev' is the old level of w
235 level.set(w,++newlevel);
240 if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty.
242 for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
243 if (level.get(v) > lev && level.get(v) < n ) level.set(v,n);
245 for (int i=lev+1 ; i!=n ; ++i) numb[i]=0;
246 if ( newlevel < n ) newlevel=n;
248 if ( newlevel < n ) ++numb[newlevel];
252 stack[newlevel].push(w);
260 value = excess.get(t);
271 Returns the maximum value of a flow.
281 For the maximum flow x found by the algorithm,
282 it returns the flow value on edge e, i.e. x(e).
285 T flowOnEdge(const EdgeIt e) {
292 Returns the maximum flow x found by the algorithm.
303 Returns the minimum min cut, by a bfs from s in the residual graph.
306 template<typename CutMap>
307 void minCut(CutMap& M) {
309 std::queue<NodeIt> queue;
314 while (!queue.empty()) {
315 NodeIt w=queue.front();
318 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
320 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
326 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
328 if (!M.get(v) && flow.get(e) > 0 ) {
340 Returns the maximum min cut, by a reverse bfs
341 from t in the residual graph.
344 template<typename CutMap>
345 void maxMinCut(CutMap& M) {
347 std::queue<NodeIt> queue;
352 while (!queue.empty()) {
353 NodeIt w=queue.front();
356 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
358 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
364 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
366 if (!M.get(v) && flow.get(e) > 0 ) {
373 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
381 template<typename CutMap>
382 void minMinCut(CutMap& M) {