.
3 //kerdesek: nem tudom lehet-e a
4 //kieleket csak a legf n szintu pontokra nezni.
9 Runs the highest label variant of the preflow push algorithm with
10 running time O(n^2\sqrt(m)), and with the 'empty level' heuristic.
12 'A' is a parameter for the empty_level heuristic
16 void run() : runs the algorithm
18 The following functions should be used after run() was already run.
20 T maxflow() : returns the value of a maximum flow
22 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e)
24 FlowMap allflow() : returns the fixed maximum flow x
26 void mincut(CutMap& M) : sets M to the characteristic vector of a
27 minimum cut. M should be a map of bools initialized to false.
29 void min_mincut(CutMap& M) : sets M to the characteristic vector of the
30 minimum min cut. M should be a map of bools initialized to false.
32 void max_mincut(CutMap& M) : sets M to the characteristic vector of the
33 maximum min cut. M should be a map of bools initialized to false.
37 #ifndef PREFLOW_PUSH_HL_H
38 #define PREFLOW_PUSH_HL_H
48 template <typename Graph, typename T,
49 typename FlowMap=typename Graph::EdgeMap<T>, typename CapMap=typename Graph::EdgeMap<T>,
50 typename IntMap=typename Graph::NodeMap<int>, typename TMap=typename Graph::NodeMap<T> >
51 class preflow_push_hl {
53 typedef typename Graph::NodeIt NodeIt;
54 typedef typename Graph::EdgeIt EdgeIt;
55 typedef typename Graph::EachNodeIt EachNodeIt;
56 typedef typename Graph::OutEdgeIt OutEdgeIt;
57 typedef typename Graph::InEdgeIt InEdgeIt;
68 preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
69 G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
79 b is a bound on the highest level of an active node.
85 std::vector<int> numb(n);
87 The number of nodes on level i < n. It is
88 initialized to n+1, because of the reverse_bfs-part.
91 std::vector<std::stack<NodeIt> > stack(2*n-1);
92 //Stack of the active nodes in level i.
95 /*Reverse_bfs from t, to find the starting level.*/
97 std::queue<NodeIt> bfs_queue;
100 while (!bfs_queue.empty()) {
102 NodeIt v=bfs_queue.front();
104 int l=level.get(v)+1;
106 for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
108 if ( level.get(w) == n ) {
120 /* Starting flow. It is everywhere 0 at the moment. */
121 for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e)
124 if ( c == 0 ) continue;
127 if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w);
129 excess.set(w, excess.get(w)+c);
139 Push/relabel on the highest level active nodes.
141 /*While there exists an active node.*/
143 if ( stack[b].empty() ) {
148 NodeIt w=stack[b].top(); //w is a highest label active node.
150 int lev=level.get(w);
151 int exc=excess.get(w);
152 int newlevel=2*n; //In newlevel we bound the next level of w.
155 // if ( level.get(w) < n ) { //Nem tudom ez mukodik-e
156 for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
158 if ( flow.get(e) == capacity.get(e) ) continue;
162 if( lev > level.get(v) ) {
163 /*Push is allowed now*/
165 if ( excess.get(v)==0 && v != s && v !=t )
166 stack[level.get(v)].push(v);
167 /*v becomes active.*/
169 int cap=capacity.get(e);
173 if ( remcap >= exc ) {
174 /*A nonsaturating push.*/
176 flow.set(e, flo+exc);
177 excess.set(v, excess.get(v)+exc);
182 /*A saturating push.*/
185 excess.set(v, excess.get(v)+remcap);
188 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
194 for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
196 if( flow.get(e) == 0 ) continue;
200 if( lev > level.get(v) ) {
201 /*Push is allowed now*/
203 if ( excess.get(v)==0 && v != s && v !=t)
204 stack[level.get(v)].push(v);
205 /*v becomes active.*/
210 /*A nonsaturating push.*/
212 flow.set(e, flo-exc);
213 excess.set(v, excess.get(v)+exc);
217 /*A saturating push.*/
219 excess.set(v, excess.get(v)+flo);
223 } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
227 } // if w still has excess after the out edge for cycle
239 //now 'lev' is the old level of w
240 level.set(w,++newlevel);
245 if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty.
247 for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
248 if (level.get(v) > lev && level.get(v) < n ) level.set(v,n);
250 for (int i=lev+1 ; i!=n ; ++i) numb[i]=0;
251 if ( newlevel < n ) newlevel=n;
253 if ( newlevel < n ) ++numb[newlevel];
257 stack[newlevel].push(w);
265 value = excess.get(t);
276 Returns the maximum value of a flow.
286 For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e).
289 T flowonedge(const EdgeIt e) {
296 Returns the maximum flow x found by the algorithm.
307 Returns the minimum min cut, by a bfs from s in the residual graph.
310 template<typename CutMap>
311 void mincut(CutMap& M) {
313 std::queue<NodeIt> queue;
318 while (!queue.empty()) {
319 NodeIt w=queue.front();
322 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
324 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
330 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
332 if (!M.get(v) && flow.get(e) > 0 ) {
344 Returns the maximum min cut, by a reverse bfs
345 from t in the residual graph.
348 template<typename CutMap>
349 void max_mincut(CutMap& M) {
351 std::queue<NodeIt> queue;
356 while (!queue.empty()) {
357 NodeIt w=queue.front();
360 for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
362 if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
368 for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
370 if (!M.get(v) && flow.get(e) > 0 ) {
377 for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
385 template<typename CutMap>
386 void min_mincut(CutMap& M) {