.
5 Runs the highest label variant of the preflow push algorithm with
6 running time O(n^2\sqrt(m)), with the 'empty level' and with the
7 heuristic that the bound b on the active nodes is not increased
8 only when b=0, when we put b=2*n-2.
10 'A' is a parameter for the empty_level heuristic
14 void run() : runs the algorithm
16 The following functions should be used after run() was already run.
18 T maxflow() : returns the value of a maximum flow
20 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
22 FlowMap allflow() : returns the fixed maximum flow x
24 void mincut(CutMap& M) : sets M to the characteristic vector of a
25 minimum cut. M should be a map of bools initialized to false.
27 void min_mincut(CutMap& M) : sets M to the characteristic vector of the
28 minimum min cut. M should be a map of bools initialized to false.
30 void max_mincut(CutMap& M) : sets M to the characteristic vector of the
31 maximum min cut. M should be a map of bools initialized to false.
46 template <typename Graph, typename T,
47 typename FlowMap=typename Graph::EdgeMap<T>, typename CapMap=typename Graph::EdgeMap<T>,
48 typename IntMap=typename Graph::NodeMap<int>, typename TMap=typename Graph::NodeMap<T> >
51 typedef typename Graph::NodeIt NodeIt;
52 typedef typename Graph::EdgeIt EdgeIt;
53 typedef typename Graph::EachNodeIt EachNodeIt;
54 typedef typename Graph::OutEdgeIt OutEdgeIt;
55 typedef typename Graph::InEdgeIt InEdgeIt;
66 preflow_hl2(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
67 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
76 b is a bound on the highest level of an active node.
77 In the beginning it is at most n-2.
83 std::vector<int> numb(n+1);
85 The number of nodes on level i < n. It is
86 initialized to n+1, because of the reverse_bfs-part.
89 std::vector<std::stack<NodeIt> > stack(2*n-1);
90 //Stack of the active nodes in level i.
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)
121 if ( capacity.get(e) == 0 ) continue;
124 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
125 flow.set(e, capacity.get(e));
126 excess.set(w, excess.get(w)+capacity.get(e));
137 Push/relabel on the highest level active nodes.
139 /*While there exists an active node.*/
141 if ( stack[b].empty() ) {
143 if ( !no_end ) break;
154 NodeIt w=stack[b].top(); //w is a highest label active node.
156 int lev=level.get(w);
157 int exc=excess.get(w);
158 int newlevel=2*n-2; //In newlevel we bound the next level of w.
160 // if ( level.get(w) < n ) { //Nem tudom ez mukodik-e
161 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
163 if ( flow.get(e) == capacity.get(e) ) continue;
167 if( lev > level.get(v) ) {
168 /*Push is allowed now*/
170 if ( excess.get(v)==0 && v != s && v !=t )
171 stack[level.get(v)].push(v);
172 /*v becomes active.*/
174 int cap=capacity.get(e);
178 if ( remcap >= exc ) {
179 /*A nonsaturating push.*/
181 flow.set(e, flo+exc);
182 excess.set(v, excess.get(v)+exc);
187 /*A saturating push.*/
190 excess.set(v, excess.get(v)+remcap);
193 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
199 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
201 if( flow.get(e) == 0 ) continue;
205 if( lev > level.get(v) ) {
206 /*Push is allowed now*/
208 if ( excess.get(v)==0 && v != s && v !=t)
209 stack[level.get(v)].push(v);
210 /*v becomes active.*/
215 /*A nonsaturating push.*/
217 flow.set(e, flo-exc);
218 excess.set(v, excess.get(v)+exc);
222 /*A saturating push.*/
224 excess.set(v, excess.get(v)+flo);
228 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
232 } // if w still has excess after the out edge for cycle
242 //now 'lev' is the old level of w
243 level.set(w,++newlevel);
248 if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty.
250 for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
251 if (level.get(v) > lev && level.get(v) < n ) level.set(v,n);
253 for (int i=lev+1 ; i!=n ; ++i) numb[i]=0;
254 if ( newlevel < n ) newlevel=n;
256 if ( newlevel < n ) ++numb[newlevel];
260 stack[newlevel].push(w);
264 } // if stack[b] is nonempty
269 value = excess.get(t);
280 Returns the maximum value of a flow.
290 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
293 T flowonedge(EdgeIt e) {
300 Returns the maximum flow x found by the algorithm.
311 Returns the minimum min cut, by a bfs from s in the residual graph.
314 template<typename CutMap>
315 void mincut(CutMap& M) {
317 std::queue<NodeIt> queue;
322 while (!queue.empty()) {
323 NodeIt w=queue.front();
326 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
328 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
334 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
336 if (!M.get(v) && flow.get(e) > 0 ) {
349 Returns the maximum min cut, by a reverse bfs
350 from t in the residual graph.
353 template<typename CutMap>
354 void max_mincut(CutMap& M) {
356 std::queue<NodeIt> queue;
361 while (!queue.empty()) {
362 NodeIt w=queue.front();
365 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
367 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
373 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
375 if (!M.get(v) && flow.get(e) > 0 ) {
382 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
390 template<typename CutMap>
391 void min_mincut(CutMap& M) {