# HG changeset patch # User jacint # Date 1077115358 0 # Node ID a5127ecb2914901335800d8ca7eb745e00c86681 # Parent e2e18eb0fd10c619110562f88910b22d982fd5ec javitott valtozat diff -r e2e18eb0fd10 -r a5127ecb2914 src/work/jacint/preflow_push_hl.h --- a/src/work/jacint/preflow_push_hl.h Wed Feb 18 13:06:41 2004 +0000 +++ b/src/work/jacint/preflow_push_hl.h Wed Feb 18 14:42:38 2004 +0000 @@ -3,7 +3,9 @@ preflow_push_hl.h by jacint. Runs the highest label variant of the preflow push algorithm with -running time O(n^2\sqrt(m)). +running time O(n^2\sqrt(m)), and with the 'empty level' heuristic. + +'A' is a parameter for the empty_level heuristic Member functions: @@ -15,11 +17,17 @@ T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e) -Graph::EdgeMap allflow() : returns the fixed maximum flow x +FlowMap allflow() : returns the fixed maximum flow x -Graph::NodeMap mincut() : returns a - characteristic vector of a minimum cut. (An empty level - in the algorithm gives a minimum cut.) +void mincut(CutMap& M) : sets M to the characteristic vector of a + minimum cut. M should be a map of bools initialized to false. + +void min_mincut(CutMap& M) : sets M to the characteristic vector of the + minimum min cut. M should be a map of bools initialized to false. + +void max_mincut(CutMap& M) : sets M to the characteristic vector of the + maximum min cut. M should be a map of bools initialized to false. + */ #ifndef PREFLOW_PUSH_HL_H @@ -29,12 +37,13 @@ #include #include - -#include +#include namespace marci { - template + template , typename CapMap=typename Graph::EdgeMap, + typename IntMap=typename Graph::NodeMap, typename TMap=typename Graph::NodeMap > class preflow_push_hl { typedef typename Graph::NodeIt NodeIt; @@ -46,207 +55,207 @@ Graph& G; NodeIt s; NodeIt t; - typename Graph::EdgeMap flow; - typename Graph::EdgeMap capacity; + FlowMap flow; + CapMap& capacity; T value; - typename Graph::NodeMap mincutvector; - + public: - preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t, - typename Graph::EdgeMap& _capacity) : - G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity), - mincutvector(_G, true) { } + preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) : + G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { } - /* - The run() function runs the highest label preflow-push, - running time: O(n^2\sqrt(m)) - */ + + void run() { - std::cout<<"A is "< level(G); - typename Graph::NodeMap excess(G); - int n=G.nodeNum(); int b=n-2; /* b is a bound on the highest level of an active node. - In the beginning it is at most n-2. */ - std::vector numb(n); //The number of nodes on level i < n. + IntMap level(G,n); + TMap excess(G); + + std::vector numb(n); + /* + The number of nodes on level i < n. It is + initialized to n+1, because of the reverse_bfs-part. + */ + std::vector > stack(2*n-1); //Stack of the active nodes in level i. /*Reverse_bfs from t, to find the starting level.*/ - reverse_bfs bfs(G, t); - bfs.run(); - for(EachNodeIt v=G.template first(); v.valid(); ++v) - { - int dist=bfs.dist(v); - level.set(v, dist); - ++numb[dist]; + level.set(t,0); + std::queue bfs_queue; + bfs_queue.push(t); + + while (!bfs_queue.empty()) { + + NodeIt v=bfs_queue.front(); + bfs_queue.pop(); + int l=level.get(v)+1; + + for(InEdgeIt e=G.template first(v); e.valid(); ++e) { + NodeIt w=G.tail(e); + if ( level.get(w) == n ) { + bfs_queue.push(w); + ++numb[l]; + level.set(w, l); + } } + } + + level.set(s,n); - level.set(s,n); /* Starting flow. It is everywhere 0 at the moment. */ for(OutEdgeIt e=G.template first(s); e.valid(); ++e) { - if ( capacity.get(e) > 0 ) { - NodeIt w=G.head(e); - if ( w!=s ) { - if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w); - flow.set(e, capacity.get(e)); - excess.set(w, excess.get(w)+capacity.get(e)); - } + if ( capacity.get(e) == 0 ) continue; + NodeIt w=G.head(e); + if ( w!=s ) { + if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w); + flow.set(e, capacity.get(e)); + excess.set(w, excess.get(w)+capacity.get(e)); } } - + /* End of preprocessing */ - /* Push/relabel on the highest level active nodes. */ - /*While there exists an active node.*/ while (b) { - - /*We decrease the bound if there is no active node of level b.*/ - if (stack[b].empty()) { + if ( stack[b].empty() ) { --b; - } else { - - NodeIt w=stack[b].top(); //w is a highest label active node. - stack[b].pop(); + continue; + } - int newlevel=2*n-2; //In newlevel we bound the next level of w. + NodeIt w=stack[b].top(); //w is a highest label active node. + stack[b].pop(); + int lev=level.get(w); + int exc=excess.get(w); + int newlevel=2*n-2; //In newlevel we bound the next level of w. + // if ( level.get(w) < n ) { //Nem tudom ez mukodik-e for(OutEdgeIt e=G.template first(w); e.valid(); ++e) { - if ( flow.get(e) < capacity.get(e) ) { - /*e is an edge of the residual graph */ + if ( flow.get(e) == capacity.get(e) ) continue; + NodeIt v=G.head(e); + //e=wv + + if( lev > level.get(v) ) { + /*Push is allowed now*/ + + if ( excess.get(v)==0 && v != s && v !=t ) + stack[level.get(v)].push(v); + /*v becomes active.*/ + + int cap=capacity.get(e); + int flo=flow.get(e); + int remcap=cap-flo; + + if ( remcap >= exc ) { + /*A nonsaturating push.*/ + + flow.set(e, flo+exc); + excess.set(v, excess.get(v)+exc); + exc=0; + break; + + } else { + /*A saturating push.*/ + + flow.set(e, cap ); + excess.set(v, excess.get(v)+remcap); + exc-=remcap; + } + } else if ( newlevel > level.get(v) ) newlevel = level.get(v); + + } //for out edges wv + + + if ( exc > 0 ) { + for( InEdgeIt e=G.template first(w); e.valid(); ++e) { + + if( flow.get(e) == 0 ) continue; + NodeIt v=G.tail(e); + //e=vw + + if( lev > level.get(v) ) { + /*Push is allowed now*/ + + if ( excess.get(v)==0 && v != s && v !=t) + stack[level.get(v)].push(v); + /*v becomes active.*/ + + int flo=flow.get(e); + + if ( flo >= exc ) { + /*A nonsaturating push.*/ + + flow.set(e, flo-exc); + excess.set(v, excess.get(v)+exc); + exc=0; + break; + } else { + /*A saturating push.*/ + + excess.set(v, excess.get(v)+flo); + exc-=flo; + flow.set(e,0); + } + } else if ( newlevel > level.get(v) ) newlevel = level.get(v); + + } //for in edges vw + + } // if w still has excess after the out edge for cycle + + excess.set(w, exc); + - NodeIt v=G.head(e); /*e is the edge wv.*/ + - if( level.get(w) == level.get(v)+1 ) { - /*Push is allowed now*/ - - if ( excess.get(v)==0 && v != s && v !=t ) stack[level.get(v)].push(v); - /*v becomes active.*/ - - if ( capacity.get(e)-flow.get(e) > excess.get(w) ) { - /*A nonsaturating push.*/ - - flow.set(e, flow.get(e)+excess.get(w)); - excess.set(v, excess.get(v)+excess.get(w)); - excess.set(w,0); - break; - - } else { - /*A saturating push.*/ - - excess.set(v, excess.get(v)+capacity.get(e)-flow.get(e)); - excess.set(w, excess.get(w)-capacity.get(e)+flow.get(e)); - flow.set(e, capacity.get(e)); - if ( excess.get(w)==0 ) break; - /*If w is not active any more, then we go on to the next node.*/ - - } - } else { - newlevel = newlevel < level.get(v) ? newlevel : level.get(v); + /* + Relabel + */ + + if ( exc > 0 ) { + //now 'lev' is the old level of w + level.set(w,++newlevel); + + if ( lev < n ) { + --numb[lev]; + + if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty. + + for (EachNodeIt v=G.template first(); v.valid() ; ++v) { + if (level.get(v) > lev && level.get(v) < n ) level.set(v,n); } - - } //if the out edge wv is in the res graph - - } //for out edges wv + for (int i=lev+1 ; i!=n ; ++i) numb[i]=0; + if ( newlevel < n ) newlevel=n; + } else { + if ( newlevel < n ) ++numb[newlevel]; + } + } - - if ( excess.get(w) > 0 ) { - - for( InEdgeIt e=G.template first(w); e.valid(); ++e) { - NodeIt v=G.tail(e); /*e is the edge vw.*/ - - if( flow.get(e) > 0 ) { - /*e is an edge of the residual graph */ - - if( level.get(w)==level.get(v)+1 ) { - /*Push is allowed now*/ - - if ( excess.get(v)==0 && v != s && v !=t) stack[level.get(v)].push(v); - /*v becomes active.*/ - - if ( flow.get(e) > excess.get(w) ) { - /*A nonsaturating push.*/ - - flow.set(e, flow.get(e)-excess.get(w)); - excess.set(v, excess.get(v)+excess.get(w)); - excess.set(w,0); - break; - } else { - /*A saturating push.*/ - - excess.set(v, excess.get(v)+flow.get(e)); - excess.set(w, excess.get(w)-flow.get(e)); - flow.set(e,0); - if ( excess.get(w)==0 ) break; - } - } else { - newlevel = newlevel < level.get(v) ? newlevel : level.get(v); - } - - } //if in edge vw is in the res graph - - } //for in edges vw - - } // if w still has excess after the out edge for cycle - - - /* - Relabel - */ + stack[newlevel].push(w); + b=newlevel; - if ( excess.get(w) > 0 ) { - - int oldlevel=level.get(w); - level.set(w,++newlevel); - - if ( oldlevel < n ) { - --numb[oldlevel]; - - if ( !numb[oldlevel] && oldlevel < A*n ) { //If the level of w gets empty. - - for (EachNodeIt v=G.template first(); v.valid() ; ++v) { - if (level.get(v) > oldlevel && level.get(v) < n ) level.set(v,n); - } - for (int i=oldlevel+1 ; i!=n ; ++i) numb[i]=0; - if ( newlevel < n ) newlevel=n; - } else { - if ( newlevel < n ) ++numb[newlevel]; - } - } else { - if ( newlevel < n ) ++numb[newlevel]; - } - - stack[newlevel].push(w); - b=newlevel; - - } - - } // if stack[b] is nonempty - + } + } // while(b) - - + + value = excess.get(t); /*Max flow value.*/ @@ -271,7 +280,7 @@ For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e). */ - T flowonedge(EdgeIt e) { + T flowonedge(const EdgeIt e) { return flow.get(e); } @@ -281,21 +290,61 @@ Returns the maximum flow x found by the algorithm. */ - typename Graph::EdgeMap allflow() { + FlowMap allflow() { return flow; } + /* - Returns a minimum cut by using a reverse bfs from t in the residual graph. + Returns the minimum min cut, by a bfs from s in the residual graph. */ - typename Graph::NodeMap mincut() { + template + void mincut(CutMap& M) { std::queue queue; - mincutvector.set(t,false); + M.set(s,true); + queue.push(s); + + while (!queue.empty()) { + NodeIt w=queue.front(); + queue.pop(); + + for(OutEdgeIt e=G.template first(w) ; e.valid(); ++e) { + NodeIt v=G.head(e); + if (!M.get(v) && flow.get(e) < capacity.get(e) ) { + queue.push(v); + M.set(v, true); + } + } + + for(InEdgeIt e=G.template first(w) ; e.valid(); ++e) { + NodeIt v=G.tail(e); + if (!M.get(v) && flow.get(e) > 0 ) { + queue.push(v); + M.set(v, true); + } + } + + } + } + + + + /* + Returns the maximum min cut, by a reverse bfs + from t in the residual graph. + */ + + template + void max_mincut(CutMap& M) { + + std::queue queue; + + M.set(t,true); queue.push(t); while (!queue.empty()) { @@ -304,25 +353,36 @@ for(InEdgeIt e=G.template first(w) ; e.valid(); ++e) { NodeIt v=G.tail(e); - if (mincutvector.get(v) && flow.get(e) < capacity.get(e) ) { + if (!M.get(v) && flow.get(e) < capacity.get(e) ) { queue.push(v); - mincutvector.set(v, false); + M.set(v, true); } - } // for + } for(OutEdgeIt e=G.template first(w) ; e.valid(); ++e) { NodeIt v=G.head(e); - if (mincutvector.get(v) && flow.get(e) > 0 ) { + if (!M.get(v) && flow.get(e) > 0 ) { queue.push(v); - mincutvector.set(v, false); + M.set(v, true); } - } // for - + } } - return mincutvector; - + for(EachNodeIt v=G.template first() ; v.valid(); ++v) { + M.set(v, !M.get(v)); + } + } + + + + template + void min_mincut(CutMap& M) { + mincut(M); + } + + + }; }//namespace marci #endif diff -r e2e18eb0fd10 -r a5127ecb2914 src/work/jacint/preflow_push_max_flow.h --- a/src/work/jacint/preflow_push_max_flow.h Wed Feb 18 13:06:41 2004 +0000 +++ b/src/work/jacint/preflow_push_max_flow.h Wed Feb 18 14:42:38 2004 +0000 @@ -1,3 +1,4 @@ +// -*- C++ -*- /* preflow_push_max_flow_h by jacint. @@ -15,13 +16,16 @@ T maxflow() : returns the value of a maximum flow -NodeMap mincut(): returns a - characteristic vector of a minimum cut. +void mincut(CutMap& M) : sets M to the characteristic vector of a + minimum cut. M should be a map of bools initialized to false. + */ #ifndef PREFLOW_PUSH_MAX_FLOW_H #define PREFLOW_PUSH_MAX_FLOW_H +#define A 1 + #include #include #include @@ -31,7 +35,9 @@ namespace marci { - template + template , typename CapMap=typename Graph::EdgeMap, + typename IntMap=typename Graph::NodeMap, typename TMap=typename Graph::NodeMap > class preflow_push_max_flow { typedef typename Graph::NodeIt NodeIt; @@ -42,17 +48,15 @@ Graph& G; NodeIt s; NodeIt t; - typename Graph::EdgeMap& capacity; - T value; - typename Graph::NodeMap mincutvector; - - - + IntMap level; + CapMap& capacity; + int empty_level; //an empty level in the end of run() + T value; + public: - - preflow_push_max_flow ( Graph& _G, NodeIt _s, NodeIt _t, - typename Graph::EdgeMap& _capacity) : - G(_G), s(_s), t(_t), capacity(_capacity), mincutvector(_G, false) { } + + preflow_push_max_flow(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) : + G(_G), s(_s), t(_t), level(_G), capacity(_capacity) { } /* @@ -62,223 +66,200 @@ */ void run() { - typename Graph::EdgeMap flow(G, 0); - typename Graph::NodeMap level(G); - typename Graph::NodeMap excess(G); - - int n=G.nodeNum(); + int n=G.nodeNum(); int b=n-2; /* - b is a bound on the highest level of an active Node. - In the beginning it is at most n-2. + b is a bound on the highest level of an active node. */ - - std::vector numb(n); //The number of Nodes on level i < n. - std::vector > stack(2*n-1); - //Stack of the active Nodes in level i. + + IntMap level(G,n); + TMap excess(G); + FlowMap flow(G,0); + + std::vector numb(n); + /* + The number of nodes on level i < n. It is + initialized to n+1, because of the reverse_bfs-part. + */ + + std::vector > stack(n); + //Stack of the active nodes in level i. + /*Reverse_bfs from t, to find the starting level.*/ - reverse_bfs bfs(G, t); - bfs.run(); - for(EachNodeIt v=G.template first(); v.valid(); ++v) - { - int dist=bfs.dist(v); - level.set(v, dist); - ++numb[dist]; + level.set(t,0); + std::queue bfs_queue; + bfs_queue.push(t); + + while (!bfs_queue.empty()) { + + NodeIt v=bfs_queue.front(); + bfs_queue.pop(); + int l=level.get(v)+1; + + for(InEdgeIt e=G.template first(v); e.valid(); ++e) { + NodeIt w=G.tail(e); + if ( level.get(w) == n ) { + bfs_queue.push(w); + ++numb[l]; + level.set(w, l); + } } - + } + level.set(s,n); - /* Starting flow. It is everywhere 0 at the moment. */ + + + /* Starting flow. It is everywhere 0 at the moment. */ for(OutEdgeIt e=G.template first(s); e.valid(); ++e) { - if ( capacity.get(e) > 0 ) { - NodeIt w=G.head(e); + if ( capacity.get(e) == 0 ) continue; + NodeIt w=G.head(e); + if ( level.get(w) < n ) { + if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w); flow.set(e, capacity.get(e)); - stack[level.get(w)].push(w); excess.set(w, excess.get(w)+capacity.get(e)); } } - + /* End of preprocessing */ + /* + Push/relabel on the highest level active nodes. + */ + /*While there exists an active node.*/ + while (b) { + if ( stack[b].empty() ) { + --b; + continue; + } + + NodeIt w=stack[b].top(); //w is a highest label active node. + stack[b].pop(); + int lev=level.get(w); + int exc=excess.get(w); + int newlevel=2*n-2; //In newlevel we bound the next level of w. + + // if ( level.get(w) < n ) { //Nem tudom ez mukodik-e + for(OutEdgeIt e=G.template first(w); e.valid(); ++e) { + + if ( flow.get(e) == capacity.get(e) ) continue; + NodeIt v=G.head(e); + //e=wv + + if( lev > level.get(v) ) { + /*Push is allowed now*/ + + if ( excess.get(v)==0 && v != s && v !=t ) + stack[level.get(v)].push(v); + /*v becomes active.*/ + + int cap=capacity.get(e); + int flo=flow.get(e); + int remcap=cap-flo; + + if ( remcap >= exc ) { + /*A nonsaturating push.*/ + + flow.set(e, flo+exc); + excess.set(v, excess.get(v)+exc); + exc=0; + break; + + } else { + /*A saturating push.*/ + + flow.set(e, cap ); + excess.set(v, excess.get(v)+remcap); + exc-=remcap; + } + } else if ( newlevel > level.get(v) ) newlevel = level.get(v); + + } //for out edges wv + + + if ( exc > 0 ) { + for( InEdgeIt e=G.template first(w); e.valid(); ++e) { + + if( flow.get(e) == 0 ) continue; + NodeIt v=G.tail(e); + //e=vw + + if( lev > level.get(v) ) { + /*Push is allowed now*/ + + if ( excess.get(v)==0 && v != s && v !=t) + stack[level.get(v)].push(v); + /*v becomes active.*/ + + int flo=flow.get(e); + + if ( flo >= exc ) { + /*A nonsaturating push.*/ + + flow.set(e, flo-exc); + excess.set(v, excess.get(v)+exc); + exc=0; + break; + } else { + /*A saturating push.*/ + + excess.set(v, excess.get(v)+flo); + exc-=flo; + flow.set(e,0); + } + } else if ( newlevel > level.get(v) ) newlevel = level.get(v); + + } //for in edges vw + + } // if w still has excess after the out edge for cycle + + excess.set(w, exc); + + + /* + Relabel + */ + + if ( exc > 0 ) { + //now 'lev' is the old level of w + level.set(w,++newlevel); + --numb[lev]; + + if ( !numb[lev] && lev < A*n ) { //If the level of w gets empty. + + for (EachNodeIt v=G.template first(); v.valid() ; ++v) { + if (level.get(v) > lev ) level.set(v,n); + } + for (int i=lev+1 ; i!=n ; ++i) numb[i]=0; + if ( newlevel < n ) newlevel=n; + } else if ( newlevel < n ) { + ++numb[newlevel]; + stack[newlevel].push(w); + b=newlevel; + } + } - /* - Push/relabel on the highest level active Nodes. - */ - - /*While there exists an active Node.*/ - while (b) { - /*We decrease the bound if there is no active node of level b.*/ - if (stack[b].empty()) { - --b; - } else { - NodeIt w=stack[b].top(); //w is the highest label active Node. - stack[b].pop(); //We delete w from the stack. - - int newlevel=2*n-2; //In newlevel we maintain the next level of w. - - for(OutEdgeIt e=G.template first(w); e.valid(); ++e) { - NodeIt v=G.head(e); - /*e is the Edge wv.*/ - - if (flow.get(e) excess.get(w)) { - /*A nonsaturating push.*/ - - if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v); - /*v becomes active.*/ - - flow.set(e, flow.get(e)+excess.get(w)); - excess.set(v, excess.get(v)+excess.get(w)); - excess.set(w,0); - //std::cout << w << " " << v <<" elore elen nonsat pump " << std::endl; - break; - } else { - /*A saturating push.*/ - - if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v); - /*v becomes active.*/ - - excess.set(v, excess.get(v)+capacity.get(e)-flow.get(e)); - excess.set(w, excess.get(w)-capacity.get(e)+flow.get(e)); - flow.set(e, capacity.get(e)); - //std::cout << w <<" " << v <<" elore elen sat pump " << std::endl; - if (excess.get(w)==0) break; - /*If w is not active any more, then we go on to the next Node.*/ - - } // if (capacity.get(e)-flow.get(e) > excess.get(w)) - } // if (level.get(w)==level.get(v)+1) - - else {newlevel = newlevel < level.get(v) ? newlevel : level.get(v);} - - } //if (flow.get(e)(w); e.valid(); ++e) { - NodeIt v=G.tail(e); - /*e is the Edge vw.*/ - - if (excess.get(w)==0) break; - /*It may happen, that w became inactive in the first 'for' cycle.*/ - - if(flow.get(e)>0) { - /*e is an Edge of the residual graph */ - - if(level.get(w)==level.get(v)+1) { - /*Push is allowed now*/ - - if (flow.get(e) > excess.get(w)) { - /*A nonsaturating push.*/ - - if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v); - /*v becomes active.*/ - - flow.set(e, flow.get(e)-excess.get(w)); - excess.set(v, excess.get(v)+excess.get(w)); - excess.set(w,0); - //std::cout << v << " " << w << " vissza elen nonsat pump " << std::endl; - break; - } else { - /*A saturating push.*/ - - if (excess.get(v)==0 && v != s) stack[level.get(v)].push(v); - /*v becomes active.*/ - - flow.set(e,0); - excess.set(v, excess.get(v)+flow.get(e)); - excess.set(w, excess.get(w)-flow.get(e)); - //std::cout << v <<" " << w << " vissza elen sat pump " << std::endl; - if (excess.get(w)==0) { break;} - } //if (flow.get(e) > excess.get(v)) - } //if(level.get(w)==level.get(v)+1) - - else {newlevel = newlevel < level.get(v) ? newlevel : level.get(v);} - //std::cout << "Leveldecrease of Node " << w << " to " << newlevel << std::endl; - - } //if (flow.get(e)>0) - - } //for in-Edge - - - - - /* - Relabel - */ - if (excess.get(w)>0) { - /*Now newlevel <= n*/ - - int l=level.get(w); //l is the old level of w. - --numb[l]; - - if (newlevel == n) { - level.set(w,n); - - } else { - - if (numb[l]) { - /*If the level of w remains nonempty.*/ - - level.set(w,++newlevel); - ++numb[newlevel]; - stack[newlevel].push(w); - b=newlevel; - } else { - /*If the level of w gets empty.*/ - - for (EachNodeIt v=G.template first(); v.valid() ; ++v) { - if (level.get(v) >= l ) { - level.set(v,n); - } - } - - for (int i=l+1 ; i!=n ; ++i) numb[i]=0; - } //if (numb[l]) - - } // if (newlevel = n) - - } // if (excess.get(w)>0) - - - } //else - } //while(b) value=excess.get(t); /*Max flow value.*/ - - /* - We find an empty level, e. The Nodes above this level give - a minimum cut. + /* + We count empty_level. The nodes above this level is a mincut. */ - - int e=1; - - while(e) { - if(numb[e]) ++e; + while(true) { + if(numb[empty_level]) ++empty_level; else break; } - for (EachNodeIt v=G.template first(); v.valid(); ++v) { - if (level.get(v) > e) mincutvector.set(v, true); - } - } // void run() @@ -295,12 +276,15 @@ /* Returns a minimum cut. - */ - - typename Graph::NodeMap mincut() { - return mincutvector; + */ + template + void mincut(CutMap& M) { + + for (EachNodeIt v=G.template first(); v.valid(); ++v) { + if ( level.get(v) > empty_level ) M.set(v, true); + } } - + }; }//namespace marci