Index: .hgignore
===================================================================
--- .hgignore	(revision 610)
+++ .hgignore	(revision 944)
@@ -23,4 +23,5 @@
 lemon/stamp-h2
 doc/Doxyfile
+doc/references.dox
 cmake/version.cmake
 .dirstamp
Index: LICENSE
===================================================================
--- LICENSE	(revision 600)
+++ LICENSE	(revision 959)
@@ -2,5 +2,5 @@
 copyright/license.
 
-Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
+Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi
 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
 EGRES).
Index: README
===================================================================
--- README	(revision 705)
+++ README	(revision 921)
@@ -18,4 +18,8 @@
    Copying, distribution and modification conditions and terms.
 
+NEWS
+
+   News and version history.
+
 INSTALL
 
@@ -34,4 +38,8 @@
    Some example programs to make you easier to get familiar with LEMON.
 
+scripts/
+
+   Scripts that make it easier to develop LEMON.
+
 test/
 
Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 463)
+++ demo/arg_parser_demo.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -66,7 +66,16 @@
     .other("...");
 
+  // Throw an exception when problems occurs. The default behavior is to
+  // exit(1) on these cases, but this makes Valgrind falsely warn
+  // about memory leaks.
+  ap.throwOnProblems();
+
   // Perform the parsing process
   // (in case of any error it terminates the program)
-  ap.parse();
+  // The try {} construct is necessary only if the ap.trowOnProblems()
+  // setting is in use.
+  try {
+    ap.parse();
+  } catch (ArgParserException &) { return 1; }
 
   // Check each option if it has been given and print its value
Index: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 895)
+++ doc/CMakeLists.txt	(revision 943)
@@ -21,4 +21,5 @@
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
Index: doc/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 895)
+++ doc/Makefile.am	(revision 943)
@@ -28,4 +28,5 @@
 	connected_components.eps \
 	edge_biconnected_components.eps \
+	matching.eps \
 	node_biconnected_components.eps \
 	planar.eps \
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 879)
+++ doc/groups.dox	(revision 959)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -264,12 +264,4 @@
 
 /**
-@defgroup matrices Matrices
-@ingroup datas
-\brief Two dimensional data storages implemented in LEMON.
-
-This group contains two dimensional data storages implemented in LEMON.
-*/
-
-/**
 @defgroup auxdat Auxiliary Data Structures
 @ingroup datas
@@ -387,5 +379,5 @@
 problem of maximum flow.
 
-\ref Circulation is a preflow push-relabel algorithm implemented directly 
+\ref Circulation is a preflow push-relabel algorithm implemented directly
 for finding feasible circulations, which is a somewhat different problem,
 but it is strongly related to maximum flow.
@@ -473,17 +465,17 @@
 
 LEMON contains three algorithms for solving the minimum mean cycle problem:
-- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
+- \ref KarpMmc Karp's original algorithm \ref amo93networkflows,
   \ref dasdan98minmeancycle.
-- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
+- \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
   version of Karp's algorithm \ref dasdan98minmeancycle.
-- \ref Howard "Howard"'s policy iteration algorithm
+- \ref HowardMmc Howard's policy iteration algorithm
   \ref dasdan98minmeancycle.
 
-In practice, the Howard algorithm proved to be by far the most efficient
-one, though the best known theoretical bound on its running time is
-exponential.
-Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
-O(n<sup>2</sup>+e), but the latter one is typically faster due to the
-applied early termination scheme.
+In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
+most efficient one, though the best known theoretical bound on its running
+time is exponential.
+Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
+run in time O(ne) and use space O(n<sup>2</sup>+e), but the latter one is
+typically faster due to the applied early termination scheme.
 */
 
@@ -523,7 +515,14 @@
   Edmond's blossom shrinking algorithm for calculating maximum weighted
   perfect matching in general graphs.
-
-\image html bipartite_matching.png
-\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
+- \ref MaxFractionalMatching Push-relabel algorithm for calculating
+  maximum cardinality fractional matching in general graphs.
+- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
+  maximum weighted fractional matching in general graphs.
+- \ref MaxWeightedPerfectFractionalMatching
+  Augmenting path algorithm for calculating maximum weighted
+  perfect fractional matching in general graphs.
+
+\image html matching.png
+\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
 */
 
Index: doc/images/matching.eps
===================================================================
--- doc/images/matching.eps	(revision 943)
+++ doc/images/matching.eps	(revision 943)
@@ -0,0 +1,130 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Sun Mar 14 09:08:34 2010
+%%BoundingBox: -353 -264 559 292
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/nmale {
+  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto
+  5 index 4 index 1 mul 1.5 mul add
+  5 index 5 index 3 sqrt 1.5 mul mul add
+  1 index 1 index lineto
+  1 index 1 index 7 index sub moveto
+  1 index 1 index lineto
+  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+  stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+%Arcs:
+gsave
+140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
+82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
+336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
+53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
+-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
+-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
+533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
+-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
+399.144 166.894 533.603 13.109 1 0 0 11.9813 l
+39.87 175.035 140.321 266.249 1 0 0 11.9813 l
+399.144 166.894 140.321 266.249 0 0 0 4.99223 l
+399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
+82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
+258.227 61.658 399.144 166.894 0 0 0 4.99223 l
+53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
+175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 380 0 0 0 0 4.99223 l
+34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
+380 0 533.603 13.109 0 0 0 4.99223 l
+175.073 -37.4477 380 0 0 0 0 4.99223 l
+218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
+53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
+167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
+336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
+336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
+329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
+53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
+34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
+175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
+380 0 329.08 -26.3098 1 0 0 11.9813 l
+grestore
+%Nodes:
+gsave
+-245.288 -110.743 14.9767 1 1 1 nc
+204.765 -173.77 14.9767 1 1 1 nc
+-327.729 150.06 14.9767 1 1 1 nc
+-75.5617 118.579 14.9767 1 1 1 nc
+218.184 -84.2955 14.9767 1 1 1 nc
+140.321 266.249 14.9767 1 1 1 nc
+141.163 67.2575 14.9767 1 1 1 nc
+82.1207 -238.726 14.9767 1 1 1 nc
+329.08 -26.3098 14.9767 1 1 1 nc
+-102.406 -141.267 14.9767 1 1 1 nc
+533.603 13.109 14.9767 1 1 1 nc
+167.905 -213.988 14.9767 1 1 1 nc
+336.635 -229.036 14.9767 1 1 1 nc
+380 0 14.9767 1 1 1 nc
+399.144 166.894 14.9767 1 1 1 nc
+34.6739 40.8267 14.9767 1 1 1 nc
+39.87 175.035 14.9767 1 1 1 nc
+175.073 -37.4477 14.9767 1 1 1 nc
+53.8598 -45.8071 14.9767 1 1 1 nc
+258.227 61.658 14.9767 1 1 1 nc
+grestore
+grestore
+showpage
Index: doc/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 802)
+++ doc/mainpage.dox	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,7 +24,7 @@
 <b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
 and <b>O</b>ptimization in <b>N</b>etworks</i>.
-It is a C++ template library providing efficient implementation of common
+It is a C++ template library providing efficient implementations of common
 data structures and algorithms with focus on combinatorial optimization
-problems in graphs and networks.
+tasks connected mainly with graphs and networks.
 
 <b>
@@ -36,10 +36,10 @@
 </b>
 
-The project is maintained by the 
+The project is maintained by the
 <a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
 Combinatorial Optimization</a> \ref egres
 at the Operations Research Department of the
-<a href="http://www.elte.hu/">E&ouml;tv&ouml;s Lor&aacute;nd University,
-Budapest</a>, Hungary.
+<a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
+Budapest, Hungary.
 LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
 initiative \ref coinor.
@@ -50,4 +50,8 @@
 <a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
 
+If you are interested in starting to use the library, see the <a class="el"
+href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
+Guide</a>.
+
 If you know what you are looking for, then try to find it under the
 <a class="el" href="modules.html">Modules</a> section.
Index: doc/min_cost_flow.dox
===================================================================
--- doc/min_cost_flow.dox	(revision 835)
+++ doc/min_cost_flow.dox	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -82,5 +82,5 @@
    - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
      then \f$\pi(u)=0\f$.
- 
+
 Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
 \f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
@@ -120,5 +120,5 @@
 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
 
-It means that the total demand must be less or equal to the 
+It means that the total demand must be less or equal to the
 total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
 positive) and all the demands have to be satisfied, but there
Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 888)
+++ lemon/Makefile.am	(revision 953)
@@ -61,5 +61,5 @@
 	lemon/bfs.h \
 	lemon/bin_heap.h \
-	lemon/binom_heap.h \
+	lemon/binomial_heap.h \
 	lemon/bucket_heap.h \
 	lemon/capacity_scaling.h \
@@ -76,4 +76,5 @@
 	lemon/cycle_canceling.h \
 	lemon/dfs.h \
+	lemon/dheap.h \
 	lemon/dijkstra.h \
 	lemon/dim2.h \
@@ -84,5 +85,5 @@
 	lemon/euler.h \
 	lemon/fib_heap.h \
-	lemon/fourary_heap.h \
+	lemon/fractional_matching.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
@@ -90,9 +91,8 @@
 	lemon/graph_to_eps.h \
 	lemon/grid_graph.h \
-	lemon/hartmann_orlin.h \
-	lemon/howard.h \
+	lemon/hartmann_orlin_mmc.h \
+	lemon/howard_mmc.h \
 	lemon/hypercube_graph.h \
-	lemon/karp.h \
-	lemon/kary_heap.h \
+	lemon/karp_mmc.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
@@ -113,4 +113,5 @@
 	lemon/planarity.h \
 	lemon/preflow.h \
+	lemon/quad_heap.h \
 	lemon/radix_heap.h \
 	lemon/radix_sort.h \
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 834)
+++ lemon/adaptors.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -422,5 +422,5 @@
       Parent::initialize(digraph);
       _node_filter = &node_filter;
-      _arc_filter = &arc_filter;      
+      _arc_filter = &arc_filter;
     }
 
@@ -509,9 +509,9 @@
 
     template <typename V>
-    class NodeMap 
-      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
-	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+    class NodeMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
       typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
-	LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
 
     public:
@@ -536,7 +536,7 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
-	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
       typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
         LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
@@ -583,5 +583,5 @@
       Parent::initialize(digraph);
       _node_filter = &node_filter;
-      _arc_filter = &arc_filter;      
+      _arc_filter = &arc_filter;
     }
 
@@ -652,8 +652,8 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
           LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
-      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
         LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
 
@@ -679,5 +679,5 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
           LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
@@ -1022,8 +1022,8 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 
@@ -1049,8 +1049,8 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 
@@ -1076,8 +1076,8 @@
 
     template <typename V>
-    class EdgeMap 
+    class EdgeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 
@@ -1118,6 +1118,6 @@
     NF* _node_filter;
     EF* _edge_filter;
-    SubGraphBase() 
-	  : Parent(), _node_filter(0), _edge_filter(0) { }
+    SubGraphBase()
+          : Parent(), _node_filter(0), _edge_filter(0) { }
 
     void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
@@ -1220,8 +1220,8 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 
@@ -1247,8 +1247,8 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 
@@ -1274,9 +1274,9 @@
 
     template <typename V>
-    class EdgeMap 
+    class EdgeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
-	LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 
     public:
@@ -1505,5 +1505,5 @@
 #endif
     typedef DigraphAdaptorExtender<
-      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
                      true> > Parent;
 
@@ -1526,5 +1526,5 @@
     /// Creates a subgraph for the given digraph or graph with the
     /// given node filter map.
-    FilterNodes(GR& graph, NF& node_filter) 
+    FilterNodes(GR& graph, NF& node_filter)
       : Parent(), const_true_map()
     {
@@ -1564,9 +1564,9 @@
                     typename enable_if<UndirectedTagIndicator<GR> >::type> :
     public GraphAdaptorExtender<
-      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
                    true> > {
 
     typedef GraphAdaptorExtender<
-      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
                    true> > Parent;
 
@@ -1654,5 +1654,5 @@
 #endif
     typedef DigraphAdaptorExtender<
-      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
                      AF, false> > Parent;
 
@@ -1762,9 +1762,9 @@
   class FilterEdges :
     public GraphAdaptorExtender<
-      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
                    EF, false> > {
 #endif
     typedef GraphAdaptorExtender<
-      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
                    EF, false> > Parent;
 
@@ -1791,5 +1791,5 @@
     /// Creates a subgraph for the given graph with the given edge
     /// filter map.
-    FilterEdges(GR& graph, EF& edge_filter) 
+    FilterEdges(GR& graph, EF& edge_filter)
       : Parent(), const_true_map() {
       Parent::initialize(graph, const_true_map, edge_filter);
@@ -1859,5 +1859,5 @@
       bool _forward;
 
-      Arc(const Edge& edge, bool forward) 
+      Arc(const Edge& edge, bool forward)
         : _edge(edge), _forward(forward) {}
 
@@ -2099,5 +2099,5 @@
 
       ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
-        : _forward(*adaptor._digraph, value), 
+        : _forward(*adaptor._digraph, value),
           _backward(*adaptor._digraph, value) {}
 
@@ -2217,5 +2217,5 @@
     typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
     EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
-    
+
     typedef EdgeNotifier ArcNotifier;
     ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
@@ -2729,5 +2729,5 @@
            typename FM = CM,
            typename TL = Tolerance<typename CM::Value> >
-  class ResidualDigraph 
+  class ResidualDigraph
     : public SubDigraph<
         Undirector<const DGR>,
@@ -2786,5 +2786,5 @@
     ResidualDigraph(const DGR& digraph, const CM& capacity,
                     FM& flow, const TL& tolerance = Tolerance())
-      : Parent(), _capacity(&capacity), _flow(&flow), 
+      : Parent(), _capacity(&capacity), _flow(&flow),
         _graph(digraph), _node_filter(),
         _forward_filter(capacity, flow, tolerance),
@@ -2868,5 +2868,5 @@
 
       /// Constructor
-      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 
+      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
         : _adaptor(&adaptor) {}
 
@@ -3448,5 +3448,5 @@
     /// to get a node map of the split digraph.
     /// Its value type is inherited from the first node map type (\c IN).
-    /// \tparam IN The type of the node map for the in-nodes. 
+    /// \tparam IN The type of the node map for the in-nodes.
     /// \tparam OUT The type of the node map for the out-nodes.
     template <typename IN, typename OUT>
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 463)
+++ lemon/arg_parser.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -21,12 +21,21 @@
 namespace lemon {
 
+  void ArgParser::_terminate(ArgParserException::Reason reason) const
+  {
+    if(_exit_on_problems)
+      exit(1);
+    else throw(ArgParserException(reason));
+  }
+
+
   void ArgParser::_showHelp(void *p)
   {
     (static_cast<ArgParser*>(p))->showHelp();
-    exit(1);
+    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
   }
 
   ArgParser::ArgParser(int argc, const char * const *argv)
-    :_argc(argc), _argv(argv), _command_name(argv[0]) {
+    :_argc(argc), _argv(argv), _command_name(argv[0]),
+    _exit_on_problems(true) {
     funcOption("-help","Print a short help message",_showHelp,this);
     synonym("help","-help");
@@ -343,5 +352,5 @@
         i!=_others_help.end();++i) showHelp(i);
     for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
-    exit(1);
+    _terminate(ArgParserException::HELP);
   }
 
@@ -352,5 +361,5 @@
     std::cerr << "\nType '" << _command_name <<
       " --help' to obtain a short summary on the usage.\n\n";
-    exit(1);
+    _terminate(ArgParserException::UNKNOWN_OPT);
   }
 
@@ -415,5 +424,5 @@
       std::cerr << "\nType '" << _command_name <<
         " --help' to obtain a short summary on the usage.\n\n";
-      exit(1);
+      _terminate(ArgParserException::INVALID_OPT);
     }
   }
Index: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 463)
+++ lemon/arg_parser.h	(revision 959)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,4 +35,49 @@
 namespace lemon {
 
+  ///Exception used by ArgParser
+
+  ///Exception used by ArgParser.
+  ///
+  class ArgParserException : public Exception {
+  public:
+    /// Reasons for failure
+
+    /// Reasons for failure.
+    ///
+    enum Reason {
+      HELP,         ///< <tt>--help</tt> option was given.
+      UNKNOWN_OPT,  ///< Unknown option was given.
+      INVALID_OPT   ///< Invalid combination of options.
+    };
+
+  private:
+    Reason _reason;
+
+  public:
+    ///Constructor
+    ArgParserException(Reason r) throw() : _reason(r) {}
+    ///Virtual destructor
+    virtual ~ArgParserException() throw() {}
+    ///A short description of the exception
+    virtual const char* what() const throw() {
+      switch(_reason)
+        {
+        case HELP:
+          return "lemon::ArgParseException: ask for help";
+          break;
+        case UNKNOWN_OPT:
+          return "lemon::ArgParseException: unknown option";
+          break;
+        case INVALID_OPT:
+          return "lemon::ArgParseException: invalid combination of options";
+          break;
+        }
+      return "";
+    }
+    ///Return the reason for the failure
+    Reason reason() const {return _reason; }
+  };
+
+
   ///Command line arguments parser
 
@@ -116,4 +161,8 @@
                     const std::string &help,
                     void (*func)(void *),void *data);
+
+    bool _exit_on_problems;
+
+    void _terminate(ArgParserException::Reason reason) const;
 
   public:
@@ -381,4 +430,9 @@
     const std::vector<std::string> &files() const { return _file_args; }
 
+    ///Throw instead of exit in case of problems
+    void throwOnProblems()
+    {
+      _exit_on_problems=false;
+    }
   };
 }
Index: lemon/bellman_ford.h
===================================================================
--- lemon/bellman_ford.h	(revision 958)
+++ lemon/bellman_ford.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -29,4 +29,5 @@
 #include <lemon/error.h>
 #include <lemon/maps.h>
+#include <lemon/tolerance.h>
 #include <lemon/path.h>
 
@@ -35,6 +36,6 @@
 namespace lemon {
 
-  /// \brief Default OperationTraits for the BellmanFord algorithm class.
-  ///  
+  /// \brief Default operation traits for the BellmanFord algorithm class.
+  ///
   /// This operation traits class defines all computational operations
   /// and constants that are used in the Bellman-Ford algorithm.
@@ -42,9 +43,11 @@
   /// If the numeric type does not have infinity value, then the maximum
   /// value is used as extremal infinity value.
+  ///
+  /// \see BellmanFordToleranceOperationTraits
   template <
-    typename V, 
+    typename V,
     bool has_inf = std::numeric_limits<V>::has_infinity>
   struct BellmanFordDefaultOperationTraits {
-    /// \e
+    /// \brief Value type for the algorithm.
     typedef V Value;
     /// \brief Gives back the zero value of the type.
@@ -84,5 +87,50 @@
     }
   };
-  
+
+  /// \brief Operation traits for the BellmanFord algorithm class
+  /// using tolerance.
+  ///
+  /// This operation traits class defines all computational operations
+  /// and constants that are used in the Bellman-Ford algorithm.
+  /// The only difference between this implementation and
+  /// \ref BellmanFordDefaultOperationTraits is that this class uses
+  /// the \ref Tolerance "tolerance technique" in its \ref less()
+  /// function.
+  ///
+  /// \tparam V The value type.
+  /// \tparam eps The epsilon value for the \ref less() function.
+  /// By default, it is the epsilon value used by \ref Tolerance
+  /// "Tolerance<V>".
+  ///
+  /// \see BellmanFordDefaultOperationTraits
+#ifdef DOXYGEN
+  template <typename V, V eps>
+#else
+  template <
+    typename V,
+    V eps = Tolerance<V>::def_epsilon>
+#endif
+  struct BellmanFordToleranceOperationTraits {
+    /// \brief Value type for the algorithm.
+    typedef V Value;
+    /// \brief Gives back the zero value of the type.
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    /// \brief Gives back the positive infinity value of the type.
+    static Value infinity() {
+      return std::numeric_limits<Value>::infinity();
+    }
+    /// \brief Gives back the sum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return left + right;
+    }
+    /// \brief Gives back \c true only if the first value is less than
+    /// the second.
+    static bool less(const Value& left, const Value& right) {
+      return left + eps < right;
+    }
+  };
+
   /// \brief Default traits class of BellmanFord class.
   ///
@@ -92,5 +140,5 @@
   template<typename GR, typename LEN>
   struct BellmanFordDefaultTraits {
-    /// The type of the digraph the algorithm runs on. 
+    /// The type of the digraph the algorithm runs on.
     typedef GR Digraph;
 
@@ -108,10 +156,11 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits
+    /// \see BellmanFordDefaultOperationTraits,
+    /// BellmanFordToleranceOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
- 
-    /// \brief The type of the map that stores the last arcs of the 
+
+    /// \brief The type of the map that stores the last arcs of the
     /// shortest paths.
-    /// 
+    ///
     /// The type of the map that stores the last
     /// arcs of the shortest paths.
@@ -120,6 +169,6 @@
 
     /// \brief Instantiates a \c PredMap.
-    /// 
-    /// This function instantiates a \ref PredMap. 
+    ///
+    /// This function instantiates a \ref PredMap.
     /// \param g is the digraph to which we would like to define the
     /// \ref PredMap.
@@ -136,6 +185,6 @@
     /// \brief Instantiates a \c DistMap.
     ///
-    /// This function instantiates a \ref DistMap. 
-    /// \param g is the digraph to which we would like to define the 
+    /// This function instantiates a \ref DistMap.
+    /// \param g is the digraph to which we would like to define the
     /// \ref DistMap.
     static DistMap *createDistMap(const GR& g) {
@@ -144,9 +193,9 @@
 
   };
-  
+
   /// \brief %BellmanFord algorithm class.
   ///
   /// \ingroup shortest_path
-  /// This class provides an efficient implementation of the Bellman-Ford 
+  /// This class provides an efficient implementation of the Bellman-Ford
   /// algorithm. The maximum time complexity of the algorithm is
   /// <tt>O(ne)</tt>.
@@ -159,5 +208,5 @@
   ///
   /// The arc lengths are passed to the algorithm using a
-  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 
+  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
   /// kind of length. The type of the length values is determined by the
   /// \ref concepts::ReadMap::Value "Value" type of the length map.
@@ -189,5 +238,5 @@
     ///The type of the underlying digraph.
     typedef typename TR::Digraph Digraph;
-    
+
     /// \brief The type of the arc lengths.
     typedef typename TR::LengthMap::Value Value;
@@ -236,10 +285,10 @@
     void create_maps() {
       if(!_pred) {
-	_local_pred = true;
-	_pred = Traits::createPredMap(*_gr);
+        _local_pred = true;
+        _pred = Traits::createPredMap(*_gr);
       }
       if(!_dist) {
-	_local_dist = true;
-	_dist = Traits::createDistMap(*_gr);
+        _local_dist = true;
+        _dist = Traits::createDistMap(*_gr);
       }
       if(!_mask) {
@@ -247,7 +296,7 @@
       }
     }
-    
+
   public :
- 
+
     typedef BellmanFord Create;
 
@@ -272,9 +321,9 @@
     /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
-    struct SetPredMap 
+    struct SetPredMap
       : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
       typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
     };
-    
+
     template <class T>
     struct SetDistMapTraits : public Traits {
@@ -293,5 +342,5 @@
     /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
-    struct SetDistMap 
+    struct SetDistMap
       : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
       typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
@@ -302,6 +351,6 @@
       typedef T OperationTraits;
     };
-    
-    /// \brief \ref named-templ-param "Named parameter" for setting 
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
     /// \c OperationTraits type.
     ///
@@ -315,13 +364,13 @@
       Create;
     };
-    
+
     ///@}
 
   protected:
-    
+
     BellmanFord() {}
 
-  public:      
-    
+  public:
+
     /// \brief Constructor.
     ///
@@ -333,5 +382,5 @@
       _pred(0), _local_pred(false),
       _dist(0), _local_dist(false), _mask(0) {}
-    
+
     ///Destructor.
     ~BellmanFord() {
@@ -360,6 +409,6 @@
     BellmanFord &predMap(PredMap &map) {
       if(_local_pred) {
-	delete _pred;
-	_local_pred=false;
+        delete _pred;
+        _local_pred=false;
       }
       _pred = &map;
@@ -378,6 +427,6 @@
     BellmanFord &distMap(DistMap &map) {
       if(_local_dist) {
-	delete _dist;
-	_local_dist=false;
+        delete _dist;
+        _local_dist=false;
       }
       _dist = &map;
@@ -397,5 +446,5 @@
 
     /// \brief Initializes the internal data structures.
-    /// 
+    ///
     /// Initializes the internal data structures. The optional parameter
     /// is the initial distance of each node.
@@ -403,20 +452,20 @@
       create_maps();
       for (NodeIt it(*_gr); it != INVALID; ++it) {
-	_pred->set(it, INVALID);
-	_dist->set(it, value);
+        _pred->set(it, INVALID);
+        _dist->set(it, value);
       }
       _process.clear();
       if (OperationTraits::less(value, OperationTraits::infinity())) {
-	for (NodeIt it(*_gr); it != INVALID; ++it) {
-	  _process.push_back(it);
-	  _mask->set(it, true);
-	}
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _process.push_back(it);
+          _mask->set(it, true);
+        }
       } else {
-	for (NodeIt it(*_gr); it != INVALID; ++it) {
-	  _mask->set(it, false);
-	}
-      }
-    }
-    
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _mask->set(it, false);
+        }
+      }
+    }
+
     /// \brief Adds a new source node.
     ///
@@ -426,6 +475,6 @@
       _dist->set(source, dst);
       if (!(*_mask)[source]) {
-	_process.push_back(source);
-	_mask->set(source, true);
+        _process.push_back(source);
+        _mask->set(source, true);
       }
     }
@@ -452,24 +501,24 @@
     bool processNextRound() {
       for (int i = 0; i < int(_process.size()); ++i) {
-	_mask->set(_process[i], false);
+        _mask->set(_process[i], false);
       }
       std::vector<Node> nextProcess;
       std::vector<Value> values(_process.size());
       for (int i = 0; i < int(_process.size()); ++i) {
-	values[i] = (*_dist)[_process[i]];
+        values[i] = (*_dist)[_process[i]];
       }
       for (int i = 0; i < int(_process.size()); ++i) {
-	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
-	  Node target = _gr->target(it);
-	  Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
-	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
-	    _pred->set(target, it);
-	    _dist->set(target, relaxed);
-	    if (!(*_mask)[target]) {
-	      _mask->set(target, true);
-	      nextProcess.push_back(target);
-	    }
-	  }	  
-	}
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
       }
       _process.swap(nextProcess);
@@ -493,21 +542,21 @@
     bool processNextWeakRound() {
       for (int i = 0; i < int(_process.size()); ++i) {
-	_mask->set(_process[i], false);
+        _mask->set(_process[i], false);
       }
       std::vector<Node> nextProcess;
       for (int i = 0; i < int(_process.size()); ++i) {
-	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
-	  Node target = _gr->target(it);
-	  Value relaxed = 
-	    OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
-	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
-	    _pred->set(target, it);
-	    _dist->set(target, relaxed);
-	    if (!(*_mask)[target]) {
-	      _mask->set(target, true);
-	      nextProcess.push_back(target);
-	    }
-	  }	  
-	}
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed =
+            OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
       }
       _process.swap(nextProcess);
@@ -531,5 +580,5 @@
       int num = countNodes(*_gr) - 1;
       for (int i = 0; i < num; ++i) {
-	if (processNextWeakRound()) break;
+        if (processNextWeakRound()) break;
       }
     }
@@ -543,16 +592,16 @@
     /// if the digraph contains cycles with negative total length.
     ///
-    /// The algorithm computes 
+    /// The algorithm computes
     /// - the shortest path tree (forest),
     /// - the distance of each node from the root(s).
-    /// 
+    ///
     /// \return \c false if there is a negative cycle in the digraph.
     ///
     /// \pre init() must be called and at least one root node should be
-    /// added with addSource() before using this function. 
+    /// added with addSource() before using this function.
     bool checkedStart() {
       int num = countNodes(*_gr);
       for (int i = 0; i < num; ++i) {
-	if (processNextWeakRound()) return true;
+        if (processNextWeakRound()) return true;
       }
       return _process.empty();
@@ -578,13 +627,13 @@
     ///
     /// \pre init() must be called and at least one root node should be
-    /// added with addSource() before using this function. 
+    /// added with addSource() before using this function.
     void limitedStart(int num) {
       for (int i = 0; i < num; ++i) {
-	if (processNextRound()) break;
-      }
-    }
-    
+        if (processNextRound()) break;
+      }
+    }
+
     /// \brief Runs the algorithm from the given root node.
-    ///    
+    ///
     /// This method runs the Bellman-Ford algorithm from the given root
     /// node \c s in order to compute the shortest path to each node.
@@ -605,8 +654,8 @@
       start();
     }
-    
+
     /// \brief Runs the algorithm from the given root node with arc
     /// number limit.
-    ///    
+    ///
     /// This method runs the Bellman-Ford algorithm from the given root
     /// node \c s in order to compute the shortest path distance for each
@@ -634,5 +683,5 @@
       limitedStart(num);
     }
-    
+
     ///@}
 
@@ -649,5 +698,5 @@
       ///
       /// Constructor for getting the active nodes of the given BellmanFord
-      /// instance. 
+      /// instance.
       ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
       {
@@ -663,5 +712,5 @@
       ///
       /// Conversion to \c Node.
-      operator Node() const { 
+      operator Node() const {
         return _index >= 0 ? _algorithm->_process[_index] : INVALID;
       }
@@ -672,31 +721,31 @@
       ActiveIt& operator++() {
         --_index;
-        return *this; 
-      }
-
-      bool operator==(const ActiveIt& it) const { 
-        return static_cast<Node>(*this) == static_cast<Node>(it); 
-      }
-      bool operator!=(const ActiveIt& it) const { 
-        return static_cast<Node>(*this) != static_cast<Node>(it); 
-      }
-      bool operator<(const ActiveIt& it) const { 
-        return static_cast<Node>(*this) < static_cast<Node>(it); 
-      }
-      
+        return *this;
+      }
+
+      bool operator==(const ActiveIt& it) const {
+        return static_cast<Node>(*this) == static_cast<Node>(it);
+      }
+      bool operator!=(const ActiveIt& it) const {
+        return static_cast<Node>(*this) != static_cast<Node>(it);
+      }
+      bool operator<(const ActiveIt& it) const {
+        return static_cast<Node>(*this) < static_cast<Node>(it);
+      }
+
     private:
       const BellmanFord* _algorithm;
       int _index;
     };
-    
+
     /// \name Query Functions
     /// The result of the Bellman-Ford algorithm can be obtained using these
     /// functions.\n
     /// Either \ref run() or \ref init() should be called before using them.
-    
+
     ///@{
 
     /// \brief The shortest path to the given node.
-    ///    
+    ///
     /// Gives back the shortest path to the given node from the root(s).
     ///
@@ -709,5 +758,5 @@
       return Path(*_gr, *_pred, t);
     }
-	  
+
     /// \brief The distance of the given node from the root(s).
     ///
@@ -749,8 +798,8 @@
     /// \pre Either \ref run() or \ref init() must be called before
     /// using this function.
-    Node predNode(Node v) const { 
-      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); 
-    }
-    
+    Node predNode(Node v) const {
+      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
+    }
+
     /// \brief Returns a const reference to the node map that stores the
     /// distances of the nodes.
@@ -762,5 +811,5 @@
     /// using this function.
     const DistMap &distMap() const { return *_dist;}
- 
+
     /// \brief Returns a const reference to the node map that stores the
     /// predecessor arcs.
@@ -772,5 +821,5 @@
     /// using this function.
     const PredMap &predMap() const { return *_pred; }
- 
+
     /// \brief Checks if a node is reached from the root(s).
     ///
@@ -784,5 +833,5 @@
 
     /// \brief Gives back a negative cycle.
-    ///    
+    ///
     /// This function gives back a directed cycle with negative total
     /// length if the algorithm has already found one.
@@ -811,8 +860,8 @@
       return cycle;
     }
-    
+
     ///@}
   };
- 
+
   /// \brief Default traits class of bellmanFord() function.
   ///
@@ -822,5 +871,5 @@
   template <typename GR, typename LEN>
   struct BellmanFordWizardDefaultTraits {
-    /// The type of the digraph the algorithm runs on. 
+    /// The type of the digraph the algorithm runs on.
     typedef GR Digraph;
 
@@ -838,10 +887,11 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits
+    /// \see BellmanFordDefaultOperationTraits,
+    /// BellmanFordToleranceOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
 
     /// \brief The type of the map that stores the last
     /// arcs of the shortest paths.
-    /// 
+    ///
     /// The type of the map that stores the last arcs of the shortest paths.
     /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
@@ -849,5 +899,5 @@
 
     /// \brief Instantiates a \c PredMap.
-    /// 
+    ///
     /// This function instantiates a \ref PredMap.
     /// \param g is the digraph to which we would like to define the
@@ -865,5 +915,5 @@
     /// \brief Instantiates a \c DistMap.
     ///
-    /// This function instantiates a \ref DistMap. 
+    /// This function instantiates a \ref DistMap.
     /// \param g is the digraph to which we would like to define the
     /// \ref DistMap.
@@ -878,5 +928,5 @@
     typedef lemon::Path<Digraph> Path;
   };
-  
+
   /// \brief Default traits class used by BellmanFordWizard.
   ///
@@ -885,5 +935,5 @@
   /// \tparam LEN The type of the length map.
   template <typename GR, typename LEN>
-  class BellmanFordWizardBase 
+  class BellmanFordWizardBase
     : public BellmanFordWizardDefaultTraits<GR, LEN> {
 
@@ -908,5 +958,5 @@
     public:
     /// Constructor.
-    
+
     /// This constructor does not require parameters, it initiates
     /// all of the attributes to default values \c 0.
@@ -915,17 +965,17 @@
 
     /// Constructor.
-    
+
     /// This constructor requires two parameters,
     /// others are initiated to \c 0.
     /// \param gr The digraph the algorithm runs on.
     /// \param len The length map.
-    BellmanFordWizardBase(const GR& gr, 
-			  const LEN& len) :
-      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))), 
-      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))), 
+    BellmanFordWizardBase(const GR& gr,
+                          const LEN& len) :
+      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
+      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
       _pred(0), _dist(0), _path(0), _di(0) {}
 
   };
-  
+
   /// \brief Auxiliary class for the function-type interface of the
   /// \ref BellmanFord "Bellman-Ford" algorithm.
@@ -952,5 +1002,5 @@
     typedef typename Digraph::Arc Arc;
     typedef typename Digraph::OutArcIt ArcIt;
-    
+
     typedef typename TR::LengthMap LengthMap;
     typedef typename LengthMap::Value Value;
@@ -969,5 +1019,5 @@
     /// \param gr The digraph the algorithm runs on.
     /// \param len The length map.
-    BellmanFordWizard(const Digraph& gr, const LengthMap& len) 
+    BellmanFordWizard(const Digraph& gr, const LengthMap& len)
       : TR(gr, len) {}
 
@@ -978,10 +1028,10 @@
 
     /// \brief Runs the Bellman-Ford algorithm from the given source node.
-    ///    
+    ///
     /// This method runs the Bellman-Ford algorithm from the given source
     /// node in order to compute the shortest path to each node.
     void run(Node s) {
-      BellmanFord<Digraph,LengthMap,TR> 
-	bf(*reinterpret_cast<const Digraph*>(Base::_graph), 
+      BellmanFord<Digraph,LengthMap,TR>
+        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
            *reinterpret_cast<const LengthMap*>(Base::_length));
       if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
@@ -1018,5 +1068,5 @@
       SetPredMapBase(const TR &b) : TR(b) {}
     };
-    
+
     /// \brief \ref named-templ-param "Named parameter" for setting
     /// the predecessor map.
@@ -1029,5 +1079,5 @@
       return BellmanFordWizard<SetPredMapBase<T> >(*this);
     }
-    
+
     template<class T>
     struct SetDistMapBase : public Base {
@@ -1036,5 +1086,5 @@
       SetDistMapBase(const TR &b) : TR(b) {}
     };
-    
+
     /// \brief \ref named-templ-param "Named parameter" for setting
     /// the distance map.
@@ -1077,7 +1127,7 @@
       return *this;
     }
-    
+
   };
-  
+
   /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
   /// algorithm.
@@ -1087,6 +1137,6 @@
   /// algorithm.
   ///
-  /// This function also has several \ref named-templ-func-param 
-  /// "named parameters", they are declared as the members of class 
+  /// This function also has several \ref named-templ-func-param
+  /// "named parameters", they are declared as the members of class
   /// \ref BellmanFordWizard.
   /// The following examples show how to use these parameters.
@@ -1105,5 +1155,5 @@
   BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
   bellmanFord(const GR& digraph,
-	      const LEN& length)
+              const LEN& length)
   {
     return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 891)
+++ lemon/bfs.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -83,5 +83,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a \c ReachedMap.
@@ -272,5 +273,6 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ReachedMap type.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
@@ -873,5 +875,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a ReachedMap.
@@ -1266,5 +1269,6 @@
     ///
     /// The type of the map that indicates which nodes are reached.
-    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    /// It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
 
Index: mon/binom_heap.h
===================================================================
--- lemon/binom_heap.h	(revision 754)
+++ 	(revision )
@@ -1,445 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2009
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_BINOM_HEAP_H
-#define LEMON_BINOM_HEAP_H
-
-///\file
-///\ingroup heaps
-///\brief Binomial Heap implementation.
-
-#include <vector>
-#include <utility>
-#include <functional>
-#include <lemon/math.h>
-#include <lemon/counter.h>
-
-namespace lemon {
-
-  /// \ingroup heaps
-  ///
-  ///\brief Binomial heap data structure.
-  ///
-  /// This class implements the \e binomial \e heap data structure.
-  /// It fully conforms to the \ref concepts::Heap "heap concept".
-  ///
-  /// The methods \ref increase() and \ref erase() are not efficient
-  /// in a binomial heap. In case of many calls of these operations,
-  /// it is better to use other heap structure, e.g. \ref BinHeap
-  /// "binary heap".
-  ///
-  /// \tparam PR Type of the priorities of the items.
-  /// \tparam IM A read-writable item map with \c int values, used
-  /// internally to handle the cross references.
-  /// \tparam CMP A functor class for comparing the priorities.
-  /// The default is \c std::less<PR>.
-#ifdef DOXYGEN
-  template <typename PR, typename IM, typename CMP>
-#else
-  template <typename PR, typename IM, typename CMP = std::less<PR> >
-#endif
-  class BinomHeap {
-  public:
-    /// Type of the item-int map.
-    typedef IM ItemIntMap;
-    /// Type of the priorities.
-    typedef PR Prio;
-    /// Type of the items stored in the heap.
-    typedef typename ItemIntMap::Key Item;
-    /// Functor type for comparing the priorities.
-    typedef CMP Compare;
-
-    /// \brief Type to represent the states of the items.
-    ///
-    /// Each item has a state associated to it. It can be "in heap",
-    /// "pre-heap" or "post-heap". The latter two are indifferent from the
-    /// heap's point of view, but may be useful to the user.
-    ///
-    /// The item-int map must be initialized in such way that it assigns
-    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
-    enum State {
-      IN_HEAP = 0,    ///< = 0.
-      PRE_HEAP = -1,  ///< = -1.
-      POST_HEAP = -2  ///< = -2.
-    };
-
-  private:
-    class Store;
-
-    std::vector<Store> _data;
-    int _min, _head;
-    ItemIntMap &_iim;
-    Compare _comp;
-    int _num_items;
-
-  public:
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    explicit BinomHeap(ItemIntMap &map)
-      : _min(0), _head(-1), _iim(map), _num_items(0) {}
-
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    /// \param comp The function object used for comparing the priorities.
-    BinomHeap(ItemIntMap &map, const Compare &comp)
-      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
-
-    /// \brief The number of items stored in the heap.
-    ///
-    /// This function returns the number of items stored in the heap.
-    int size() const { return _num_items; }
-
-    /// \brief Check if the heap is empty.
-    ///
-    /// This function returns \c true if the heap is empty.
-    bool empty() const { return _num_items==0; }
-
-    /// \brief Make the heap empty.
-    ///
-    /// This functon makes the heap empty.
-    /// It does not change the cross reference map. If you want to reuse
-    /// a heap that is not surely empty, you should first clear it and
-    /// then you should set the cross reference map to \c PRE_HEAP
-    /// for each item.
-    void clear() {
-      _data.clear(); _min=0; _num_items=0; _head=-1;
-    }
-
-    /// \brief Set the priority of an item or insert it, if it is
-    /// not stored in the heap.
-    ///
-    /// This method sets the priority of the given item if it is
-    /// already stored in the heap. Otherwise it inserts the given
-    /// item into the heap with the given priority.
-    /// \param item The item.
-    /// \param value The priority.
-    void set (const Item& item, const Prio& value) {
-      int i=_iim[item];
-      if ( i >= 0 && _data[i].in ) {
-        if ( _comp(value, _data[i].prio) ) decrease(item, value);
-        if ( _comp(_data[i].prio, value) ) increase(item, value);
-      } else push(item, value);
-    }
-
-    /// \brief Insert an item into the heap with the given priority.
-    ///
-    /// This function inserts the given item into the heap with the
-    /// given priority.
-    /// \param item The item to insert.
-    /// \param value The priority of the item.
-    /// \pre \e item must not be stored in the heap.
-    void push (const Item& item, const Prio& value) {
-      int i=_iim[item];
-      if ( i<0 ) {
-        int s=_data.size();
-        _iim.set( item,s );
-        Store st;
-        st.name=item;
-        st.prio=value;
-        _data.push_back(st);
-        i=s;
-      }
-      else {
-        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
-        _data[i].degree=0;
-        _data[i].in=true;
-        _data[i].prio=value;
-      }
-
-      if( 0==_num_items ) {
-        _head=i;
-        _min=i;
-      } else {
-        merge(i);
-        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
-      }
-      ++_num_items;
-    }
-
-    /// \brief Return the item having minimum priority.
-    ///
-    /// This function returns the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    Item top() const { return _data[_min].name; }
-
-    /// \brief The minimum priority.
-    ///
-    /// This function returns the minimum priority.
-    /// \pre The heap must be non-empty.
-    Prio prio() const { return _data[_min].prio; }
-
-    /// \brief The priority of the given item.
-    ///
-    /// This function returns the priority of the given item.
-    /// \param item The item.
-    /// \pre \e item must be in the heap.
-    const Prio& operator[](const Item& item) const {
-      return _data[_iim[item]].prio;
-    }
-
-    /// \brief Remove the item having minimum priority.
-    ///
-    /// This function removes the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    void pop() {
-      _data[_min].in=false;
-
-      int head_child=-1;
-      if ( _data[_min].child!=-1 ) {
-        int child=_data[_min].child;
-        int neighb;
-        while( child!=-1 ) {
-          neighb=_data[child].right_neighbor;
-          _data[child].parent=-1;
-          _data[child].right_neighbor=head_child;
-          head_child=child;
-          child=neighb;
-        }
-      }
-
-      if ( _data[_head].right_neighbor==-1 ) {
-        // there was only one root
-        _head=head_child;
-      }
-      else {
-        // there were more roots
-        if( _head!=_min )  { unlace(_min); }
-        else { _head=_data[_head].right_neighbor; }
-        merge(head_child);
-      }
-      _min=findMin();
-      --_num_items;
-    }
-
-    /// \brief Remove the given item from the heap.
-    ///
-    /// This function removes the given item from the heap if it is
-    /// already stored.
-    /// \param item The item to delete.
-    /// \pre \e item must be in the heap.
-    void erase (const Item& item) {
-      int i=_iim[item];
-      if ( i >= 0 && _data[i].in ) {
-        decrease( item, _data[_min].prio-1 );
-        pop();
-      }
-    }
-
-    /// \brief Decrease the priority of an item to the given value.
-    ///
-    /// This function decreases the priority of an item to the given value.
-    /// \param item The item.
-    /// \param value The priority.
-    /// \pre \e item must be stored in the heap with priority at least \e value.
-    void decrease (Item item, const Prio& value) {
-      int i=_iim[item];
-      int p=_data[i].parent;
-      _data[i].prio=value;
-      
-      while( p!=-1 && _comp(value, _data[p].prio) ) {
-        _data[i].name=_data[p].name;
-        _data[i].prio=_data[p].prio;
-        _data[p].name=item;
-        _data[p].prio=value;
-        _iim[_data[i].name]=i;
-        i=p;
-        p=_data[p].parent;
-      }
-      _iim[item]=i;
-      if ( _comp(value, _data[_min].prio) ) _min=i;
-    }
-
-    /// \brief Increase the priority of an item to the given value.
-    ///
-    /// This function increases the priority of an item to the given value.
-    /// \param item The item.
-    /// \param value The priority.
-    /// \pre \e item must be stored in the heap with priority at most \e value.
-    void increase (Item item, const Prio& value) {
-      erase(item);
-      push(item, value);
-    }
-
-    /// \brief Return the state of an item.
-    ///
-    /// This method returns \c PRE_HEAP if the given item has never
-    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
-    /// and \c POST_HEAP otherwise.
-    /// In the latter case it is possible that the item will get back
-    /// to the heap again.
-    /// \param item The item.
-    State state(const Item &item) const {
-      int i=_iim[item];
-      if( i>=0 ) {
-        if ( _data[i].in ) i=0;
-        else i=-2;
-      }
-      return State(i);
-    }
-
-    /// \brief Set the state of an item in the heap.
-    ///
-    /// This function sets the state of the given item in the heap.
-    /// It can be used to manually clear the heap when it is important
-    /// to achive better time complexity.
-    /// \param i The item.
-    /// \param st The state. It should not be \c IN_HEAP.
-    void state(const Item& i, State st) {
-      switch (st) {
-      case POST_HEAP:
-      case PRE_HEAP:
-        if (state(i) == IN_HEAP) {
-          erase(i);
-        }
-        _iim[i] = st;
-        break;
-      case IN_HEAP:
-        break;
-      }
-    }
-
-  private:
-    
-    // Find the minimum of the roots
-    int findMin() {
-      if( _head!=-1 ) {
-        int min_loc=_head, min_val=_data[_head].prio;
-        for( int x=_data[_head].right_neighbor; x!=-1;
-             x=_data[x].right_neighbor ) {
-          if( _comp( _data[x].prio,min_val ) ) {
-            min_val=_data[x].prio;
-            min_loc=x;
-          }
-        }
-        return min_loc;
-      }
-      else return -1;
-    }
-
-    // Merge the heap with another heap starting at the given position
-    void merge(int a) {
-      if( _head==-1 || a==-1 ) return;
-      if( _data[a].right_neighbor==-1 &&
-          _data[a].degree<=_data[_head].degree ) {
-        _data[a].right_neighbor=_head;
-        _head=a;
-      } else {
-        interleave(a);
-      }
-      if( _data[_head].right_neighbor==-1 ) return;
-      
-      int x=_head;
-      int x_prev=-1, x_next=_data[x].right_neighbor;
-      while( x_next!=-1 ) {
-        if( _data[x].degree!=_data[x_next].degree ||
-            ( _data[x_next].right_neighbor!=-1 &&
-              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
-          x_prev=x;
-          x=x_next;
-        }
-        else {
-          if( _comp(_data[x_next].prio,_data[x].prio) ) {
-            if( x_prev==-1 ) {
-              _head=x_next;
-            } else {
-              _data[x_prev].right_neighbor=x_next;
-            }
-            fuse(x,x_next);
-            x=x_next;
-          }
-          else {
-            _data[x].right_neighbor=_data[x_next].right_neighbor;
-            fuse(x_next,x);
-          }
-        }
-        x_next=_data[x].right_neighbor;
-      }
-    }
-
-    // Interleave the elements of the given list into the list of the roots
-    void interleave(int a) {
-      int p=_head, q=a;
-      int curr=_data.size();
-      _data.push_back(Store());
-      
-      while( p!=-1 || q!=-1 ) {
-        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
-          _data[curr].right_neighbor=p;
-          curr=p;
-          p=_data[p].right_neighbor;
-        }
-        else {
-          _data[curr].right_neighbor=q;
-          curr=q;
-          q=_data[q].right_neighbor;
-        }
-      }
-      
-      _head=_data.back().right_neighbor;
-      _data.pop_back();
-    }
-
-    // Lace node a under node b
-    void fuse(int a, int b) {
-      _data[a].parent=b;
-      _data[a].right_neighbor=_data[b].child;
-      _data[b].child=a;
-
-      ++_data[b].degree;
-    }
-
-    // Unlace node a (if it has siblings)
-    void unlace(int a) {
-      int neighb=_data[a].right_neighbor;
-      int other=_head;
-
-      while( _data[other].right_neighbor!=a )
-        other=_data[other].right_neighbor;
-      _data[other].right_neighbor=neighb;
-    }
-
-  private:
-
-    class Store {
-      friend class BinomHeap;
-
-      Item name;
-      int parent;
-      int right_neighbor;
-      int child;
-      int degree;
-      bool in;
-      Prio prio;
-
-      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
-        in(true) {}
-    };
-  };
-
-} //namespace lemon
-
-#endif //LEMON_BINOM_HEAP_H
-
Index: lemon/binomial_heap.h
===================================================================
--- lemon/binomial_heap.h	(revision 956)
+++ lemon/binomial_heap.h	(revision 956)
@@ -0,0 +1,445 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BINOMIAL_HEAP_H
+#define LEMON_BINOMIAL_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Binomial Heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+#include <lemon/counter.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Binomial heap data structure.
+  ///
+  /// This class implements the \e binomial \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient
+  /// in a binomial heap. In case of many calls of these operations,
+  /// it is better to use other heap structure, e.g. \ref BinHeap
+  /// "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class BinomialHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _min, _head;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num_items;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit BinomialHeap(ItemIntMap &map)
+      : _min(0), _head(-1), _iim(map), _num_items(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    BinomialHeap(ItemIntMap &map, const Compare &comp)
+      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num_items; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num_items==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _min=0; _num_items=0; _head=-1;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param value The priority.
+    void set (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        if ( _comp(value, _data[i].prio) ) decrease(item, value);
+        if ( _comp(_data[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param value The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i<0 ) {
+        int s=_data.size();
+        _iim.set( item,s );
+        Store st;
+        st.name=item;
+        st.prio=value;
+        _data.push_back(st);
+        i=s;
+      }
+      else {
+        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].prio=value;
+      }
+
+      if( 0==_num_items ) {
+        _head=i;
+        _min=i;
+      } else {
+        merge(i);
+        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
+      }
+      ++_num_items;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_min].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[_min].prio; }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      _data[_min].in=false;
+
+      int head_child=-1;
+      if ( _data[_min].child!=-1 ) {
+        int child=_data[_min].child;
+        int neighb;
+        while( child!=-1 ) {
+          neighb=_data[child].right_neighbor;
+          _data[child].parent=-1;
+          _data[child].right_neighbor=head_child;
+          head_child=child;
+          child=neighb;
+        }
+      }
+
+      if ( _data[_head].right_neighbor==-1 ) {
+        // there was only one root
+        _head=head_child;
+      }
+      else {
+        // there were more roots
+        if( _head!=_min )  { unlace(_min); }
+        else { _head=_data[_head].right_neighbor; }
+        merge(head_child);
+      }
+      _min=findMin();
+      --_num_items;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        decrease( item, _data[_min].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e value.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      int p=_data[i].parent;
+      _data[i].prio=value;
+
+      while( p!=-1 && _comp(value, _data[p].prio) ) {
+        _data[i].name=_data[p].name;
+        _data[i].prio=_data[p].prio;
+        _data[p].name=item;
+        _data[p].prio=value;
+        _iim[_data[i].name]=i;
+        i=p;
+        p=_data[p].parent;
+      }
+      _iim[item]=i;
+      if ( _comp(value, _data[_min].prio) ) _min=i;
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e value.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item, value);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if ( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    // Find the minimum of the roots
+    int findMin() {
+      if( _head!=-1 ) {
+        int min_loc=_head, min_val=_data[_head].prio;
+        for( int x=_data[_head].right_neighbor; x!=-1;
+             x=_data[x].right_neighbor ) {
+          if( _comp( _data[x].prio,min_val ) ) {
+            min_val=_data[x].prio;
+            min_loc=x;
+          }
+        }
+        return min_loc;
+      }
+      else return -1;
+    }
+
+    // Merge the heap with another heap starting at the given position
+    void merge(int a) {
+      if( _head==-1 || a==-1 ) return;
+      if( _data[a].right_neighbor==-1 &&
+          _data[a].degree<=_data[_head].degree ) {
+        _data[a].right_neighbor=_head;
+        _head=a;
+      } else {
+        interleave(a);
+      }
+      if( _data[_head].right_neighbor==-1 ) return;
+
+      int x=_head;
+      int x_prev=-1, x_next=_data[x].right_neighbor;
+      while( x_next!=-1 ) {
+        if( _data[x].degree!=_data[x_next].degree ||
+            ( _data[x_next].right_neighbor!=-1 &&
+              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
+          x_prev=x;
+          x=x_next;
+        }
+        else {
+          if( _comp(_data[x_next].prio,_data[x].prio) ) {
+            if( x_prev==-1 ) {
+              _head=x_next;
+            } else {
+              _data[x_prev].right_neighbor=x_next;
+            }
+            fuse(x,x_next);
+            x=x_next;
+          }
+          else {
+            _data[x].right_neighbor=_data[x_next].right_neighbor;
+            fuse(x_next,x);
+          }
+        }
+        x_next=_data[x].right_neighbor;
+      }
+    }
+
+    // Interleave the elements of the given list into the list of the roots
+    void interleave(int a) {
+      int p=_head, q=a;
+      int curr=_data.size();
+      _data.push_back(Store());
+
+      while( p!=-1 || q!=-1 ) {
+        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
+          _data[curr].right_neighbor=p;
+          curr=p;
+          p=_data[p].right_neighbor;
+        }
+        else {
+          _data[curr].right_neighbor=q;
+          curr=q;
+          q=_data[q].right_neighbor;
+        }
+      }
+
+      _head=_data.back().right_neighbor;
+      _data.pop_back();
+    }
+
+    // Lace node a under node b
+    void fuse(int a, int b) {
+      _data[a].parent=b;
+      _data[a].right_neighbor=_data[b].child;
+      _data[b].child=a;
+
+      ++_data[b].degree;
+    }
+
+    // Unlace node a (if it has siblings)
+    void unlace(int a) {
+      int neighb=_data[a].right_neighbor;
+      int other=_head;
+
+      while( _data[other].right_neighbor!=a )
+        other=_data[other].right_neighbor;
+      _data[other].right_neighbor=neighb;
+    }
+
+  private:
+
+    class Store {
+      friend class BinomialHeap;
+
+      Item name;
+      int parent;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
+        in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_BINOMIAL_HEAP_H
+
Index: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 664)
+++ lemon/bits/array_map.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -71,5 +71,5 @@
 
   private:
-  
+
     // The MapBase of the Map which imlements the core regisitry function.
     typedef typename Notifier::ObserverBase Parent;
Index: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 674)
+++ lemon/bits/default_map.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -158,5 +158,5 @@
   public:
     typedef DefaultMap<_Graph, _Item, _Value> Map;
-    
+
     typedef typename Parent::GraphType GraphType;
     typedef typename Parent::Value Value;
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 732)
+++ lemon/bits/edge_set_extender.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -64,9 +64,9 @@
     Node oppositeNode(const Node &n, const Arc &e) const {
       if (n == Parent::source(e))
-	return Parent::target(e);
+        return Parent::target(e);
       else if(n==Parent::target(e))
-	return Parent::source(e);
+        return Parent::source(e);
       else
-	return INVALID;
+        return INVALID;
     }
 
@@ -92,5 +92,5 @@
     // Iterable extensions
 
-    class NodeIt : public Node { 
+    class NodeIt : public Node {
       const Digraph* digraph;
     public:
@@ -101,19 +101,19 @@
 
       explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Node&>(*this));
-      }
-
-      NodeIt(const Digraph& _graph, const Node& node) 
-	: Node(node), digraph(&_graph) {}
-
-      NodeIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class ArcIt : public Arc { 
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Digraph& _graph, const Node& node)
+        : Node(node), digraph(&_graph) {}
+
+      NodeIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -124,19 +124,19 @@
 
       explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Arc&>(*this));
-      }
-
-      ArcIt(const Digraph& _graph, const Arc& e) : 
-	Arc(e), digraph(&_graph) { }
-
-      ArcIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class OutArcIt : public Arc { 
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Digraph& _graph, const Arc& e) :
+        Arc(e), digraph(&_graph) { }
+
+      ArcIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -146,21 +146,21 @@
       OutArcIt(Invalid i) : Arc(i) { }
 
-      OutArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstOut(*this, node);
-      }
-
-      OutArcIt(const Digraph& _graph, const Arc& arc) 
-	: Arc(arc), digraph(&_graph) {}
-
-      OutArcIt& operator++() { 
-	digraph->nextOut(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class InArcIt : public Arc { 
+      OutArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Digraph& _graph, const Arc& arc)
+        : Arc(arc), digraph(&_graph) {}
+
+      OutArcIt& operator++() {
+        digraph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -170,15 +170,15 @@
       InArcIt(Invalid i) : Arc(i) { }
 
-      InArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstIn(*this, node);
-      }
-
-      InArcIt(const Digraph& _graph, const Arc& arc) : 
-	Arc(arc), digraph(&_graph) {}
-
-      InArcIt& operator++() { 
-	digraph->nextIn(*this);
-	return *this; 
+      InArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Digraph& _graph, const Arc& arc) :
+        Arc(arc), digraph(&_graph) {}
+
+      InArcIt& operator++() {
+        digraph->nextIn(*this);
+        return *this;
       }
 
@@ -216,18 +216,18 @@
 
     // Mappable extension
-    
+
     template <typename _Value>
-    class ArcMap 
+    class ArcMap
       : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
       typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
 
     public:
-      explicit ArcMap(const Digraph& _g) 
-	: Parent(_g) {}
-      ArcMap(const Digraph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+      explicit ArcMap(const Digraph& _g)
+        : Parent(_g) {}
+      ArcMap(const Digraph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       ArcMap& operator=(const ArcMap& cmap) {
-	return operator=<ArcMap>(cmap);
+        return operator=<ArcMap>(cmap);
       }
 
@@ -235,5 +235,5 @@
       ArcMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -248,5 +248,5 @@
       return arc;
     }
-    
+
     void clear() {
       notifier(Arc()).clear();
@@ -311,9 +311,9 @@
     Node oppositeNode(const Node &n, const Edge &e) const {
       if( n == Parent::u(e))
-	return Parent::v(e);
+        return Parent::v(e);
       else if( n == Parent::v(e))
-	return Parent::u(e);
+        return Parent::u(e);
       else
-	return INVALID;
+        return INVALID;
     }
 
@@ -339,5 +339,5 @@
 
     using Parent::notifier;
-    
+
     ArcNotifier& notifier(Arc) const {
       return arc_notifier;
@@ -349,5 +349,5 @@
 
 
-    class NodeIt : public Node { 
+    class NodeIt : public Node {
       const Graph* graph;
     public:
@@ -358,19 +358,19 @@
 
       explicit NodeIt(const Graph& _graph) : graph(&_graph) {
-	_graph.first(static_cast<Node&>(*this));
-      }
-
-      NodeIt(const Graph& _graph, const Node& node) 
-	: Node(node), graph(&_graph) {}
-
-      NodeIt& operator++() { 
-	graph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class ArcIt : public Arc { 
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Graph& _graph, const Node& node)
+        : Node(node), graph(&_graph) {}
+
+      NodeIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
       const Graph* graph;
     public:
@@ -381,19 +381,19 @@
 
       explicit ArcIt(const Graph& _graph) : graph(&_graph) {
-	_graph.first(static_cast<Arc&>(*this));
-      }
-
-      ArcIt(const Graph& _graph, const Arc& e) : 
-	Arc(e), graph(&_graph) { }
-
-      ArcIt& operator++() { 
-	graph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class OutArcIt : public Arc { 
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Graph& _graph, const Arc& e) :
+        Arc(e), graph(&_graph) { }
+
+      ArcIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
       const Graph* graph;
     public:
@@ -403,21 +403,21 @@
       OutArcIt(Invalid i) : Arc(i) { }
 
-      OutArcIt(const Graph& _graph, const Node& node) 
-	: graph(&_graph) {
-	_graph.firstOut(*this, node);
-      }
-
-      OutArcIt(const Graph& _graph, const Arc& arc) 
-	: Arc(arc), graph(&_graph) {}
-
-      OutArcIt& operator++() { 
-	graph->nextOut(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class InArcIt : public Arc { 
+      OutArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Graph& _graph, const Arc& arc)
+        : Arc(arc), graph(&_graph) {}
+
+      OutArcIt& operator++() {
+        graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
       const Graph* graph;
     public:
@@ -427,21 +427,21 @@
       InArcIt(Invalid i) : Arc(i) { }
 
-      InArcIt(const Graph& _graph, const Node& node) 
-	: graph(&_graph) {
-	_graph.firstIn(*this, node);
-      }
-
-      InArcIt(const Graph& _graph, const Arc& arc) : 
-	Arc(arc), graph(&_graph) {}
-
-      InArcIt& operator++() { 
-	graph->nextIn(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class EdgeIt : public Parent::Edge { 
+      InArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Graph& _graph, const Arc& arc) :
+        Arc(arc), graph(&_graph) {}
+
+      InArcIt& operator++() {
+        graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
       const Graph* graph;
     public:
@@ -452,13 +452,13 @@
 
       explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
-	_graph.first(static_cast<Edge&>(*this));
-      }
-
-      EdgeIt(const Graph& _graph, const Edge& e) : 
-	Edge(e), graph(&_graph) { }
-
-      EdgeIt& operator++() { 
-	graph->next(*this);
-	return *this; 
+        _graph.first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Graph& _graph, const Edge& e) :
+        Edge(e), graph(&_graph) { }
+
+      EdgeIt& operator++() {
+        graph->next(*this);
+        return *this;
       }
 
@@ -476,15 +476,15 @@
 
       IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
-	_graph.firstInc(*this, direction, n);
+        _graph.firstInc(*this, direction, n);
       }
 
       IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
-	: graph(&_graph), Edge(ue) {
-	direction = (_graph.source(ue) == n);
+        : graph(&_graph), Edge(ue) {
+        direction = (_graph.source(ue) == n);
       }
 
       IncEdgeIt& operator++() {
-	graph->nextInc(*this, direction);
-	return *this; 
+        graph->nextInc(*this, direction);
+        return *this;
       }
     };
@@ -533,16 +533,16 @@
 
     template <typename _Value>
-    class ArcMap 
+    class ArcMap
       : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
       typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
 
     public:
-      explicit ArcMap(const Graph& _g) 
-	: Parent(_g) {}
-      ArcMap(const Graph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+      explicit ArcMap(const Graph& _g)
+        : Parent(_g) {}
+      ArcMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       ArcMap& operator=(const ArcMap& cmap) {
-	return operator=<ArcMap>(cmap);
+        return operator=<ArcMap>(cmap);
       }
 
@@ -550,5 +550,5 @@
       ArcMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -557,17 +557,17 @@
 
     template <typename _Value>
-    class EdgeMap 
+    class EdgeMap
       : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
       typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
 
     public:
-      explicit EdgeMap(const Graph& _g) 
-	: Parent(_g) {}
-
-      EdgeMap(const Graph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+      explicit EdgeMap(const Graph& _g)
+        : Parent(_g) {}
+
+      EdgeMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       EdgeMap& operator=(const EdgeMap& cmap) {
-	return operator=<EdgeMap>(cmap);
+        return operator=<EdgeMap>(cmap);
       }
 
@@ -575,5 +575,5 @@
       EdgeMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -592,5 +592,5 @@
       return edge;
     }
-    
+
     void clear() {
       notifier(Arc()).clear();
@@ -618,5 +618,5 @@
       arc_notifier.clear();
     }
-    
+
   };
 
Index: lemon/bits/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 566)
+++ lemon/bits/solver_bits.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/windows.cc
===================================================================
--- lemon/bits/windows.cc	(revision 513)
+++ lemon/bits/windows.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -97,5 +97,5 @@
       GetSystemTime(&time);
       char buf1[11], buf2[9], buf3[5];
-	  if (GetDateFormat(MY_LOCALE, 0, &time,
+          if (GetDateFormat(MY_LOCALE, 0, &time,
                         ("ddd MMM dd"), buf1, 11) &&
           GetTimeFormat(MY_LOCALE, 0, &time,
Index: lemon/bucket_heap.h
===================================================================
--- lemon/bucket_heap.h	(revision 758)
+++ lemon/bucket_heap.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -385,5 +385,5 @@
   ///
   /// Note that this implementation does not conform to the
-  /// \ref concepts::Heap "heap concept" due to the lack of some 
+  /// \ref concepts::Heap "heap concept" due to the lack of some
   /// functionality.
   ///
Index: lemon/capacity_scaling.h
===================================================================
--- lemon/capacity_scaling.h	(revision 899)
+++ lemon/capacity_scaling.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -134,5 +134,5 @@
       UNBOUNDED
     };
-  
+
   private:
 
@@ -140,7 +140,8 @@
 
     typedef std::vector<int> IntVector;
-    typedef std::vector<char> BoolVector;
     typedef std::vector<Value> ValueVector;
     typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
 
   private:
@@ -184,5 +185,5 @@
 
   public:
-  
+
     /// \brief Constant for infinite upper bounds (capacities).
     ///
@@ -211,8 +212,8 @@
       CostVector &_pi;
       IntVector &_pred;
-      
+
       IntVector _proc_nodes;
       CostVector _dist;
-      
+
     public:
 
@@ -301,4 +302,8 @@
     /// @}
 
+  protected:
+
+    CapacityScaling() {}
+
   public:
 
@@ -435,5 +440,5 @@
       return *this;
     }
-    
+
     /// @}
 
@@ -571,5 +576,5 @@
       _cost.resize(_res_arc_num);
       _supply.resize(_node_num);
-      
+
       _res_cap.resize(_res_arc_num);
       _pi.resize(_node_num);
@@ -615,5 +620,5 @@
         _reverse[bi] = fi;
       }
-      
+
       // Reset parameters
       resetParams();
@@ -724,5 +729,5 @@
       }
       if (_sum_supply > 0) return INFEASIBLE;
-      
+
       // Initialize vectors
       for (int i = 0; i != _root; ++i) {
@@ -772,5 +777,5 @@
         }
       }
-      
+
       // Handle GEQ supply type
       if (_sum_supply < 0) {
@@ -799,13 +804,13 @@
       if (_factor > 1) {
         // With scaling
-        Value max_sup = 0, max_dem = 0;
-        for (int i = 0; i != _node_num; ++i) {
+        Value max_sup = 0, max_dem = 0, max_cap = 0;
+        for (int i = 0; i != _root; ++i) {
           Value ex = _excess[i];
           if ( ex > max_sup) max_sup =  ex;
           if (-ex > max_dem) max_dem = -ex;
-        }
-        Value max_cap = 0;
-        for (int j = 0; j != _res_arc_num; ++j) {
-          if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
+          int last_out = _first_out[i+1] - 1;
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
+          }
         }
         max_sup = std::min(std::min(max_sup, max_dem), max_cap);
@@ -840,7 +845,7 @@
         for (int i = 0; i != _node_num; ++i) {
           _pi[i] -= pr;
-        }        
-      }
-      
+        }
+      }
+
       return pt;
     }
Index: lemon/cbc.h
===================================================================
--- lemon/cbc.h	(revision 793)
+++ lemon/cbc.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -122,5 +122,5 @@
     int _message_level;
 
-    
+
 
   };
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 891)
+++ lemon/circulation.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -60,6 +60,6 @@
     /// \brief The type of supply map.
     ///
-    /// The type of the map that stores the signed supply values of the 
-    /// nodes. 
+    /// The type of the map that stores the signed supply values of the
+    /// nodes.
     /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
     typedef SM SupplyMap;
@@ -142,5 +142,5 @@
      \geq sup(u) \quad \forall u\in V, \f]
      \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
-     
+
      The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
      zero or negative in order to have a feasible solution (since the sum
@@ -152,5 +152,5 @@
      constraints have to be satisfied with equality, i.e. all demands
      have to be satisfied and all supplies have to be used.
-     
+
      If you need the opposite inequalities in the supply/demand constraints
      (i.e. the total demand is less than the total supply and all the demands
@@ -338,5 +338,5 @@
     /// \param graph The digraph the algorithm runs on.
     /// \param lower The lower bounds for the flow values on the arcs.
-    /// \param upper The upper bounds (capacities) for the flow values 
+    /// \param upper The upper bounds (capacities) for the flow values
     /// on the arcs.
     /// \param supply The signed supply values of the nodes.
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 793)
+++ lemon/clp.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 793)
+++ lemon/clp.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -139,5 +139,5 @@
 
     virtual void _messageLevel(MessageLevel);
-    
+
   public:
 
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 833)
+++ lemon/concepts/digraph.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -435,5 +435,5 @@
       private:
         ///Copy constructor
-        NodeMap(const NodeMap& nm) : 
+        NodeMap(const NodeMap& nm) :
           ReferenceMap<Node, T, T&, const T&>(nm) { }
         ///Assignment operator
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 833)
+++ lemon/concepts/graph.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -44,5 +44,5 @@
     /// run properly, of course.
     /// An actual graph implementation like \ref ListGraph or
-    /// \ref SmartGraph may have additional functionality.    
+    /// \ref SmartGraph may have additional functionality.
     ///
     /// The undirected graphs also fulfill the concept of \ref Digraph
@@ -86,5 +86,5 @@
       ///
       /// Undirected graphs should be tagged with \c UndirectedTag.
-      /// 
+      ///
       /// This tag helps the \c enable_if technics to make compile time
       /// specializations for undirected graphs.
@@ -361,5 +361,5 @@
 
         /// Converison to \c Edge
-        
+
         /// Converison to \c Edge.
         ///
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 833)
+++ lemon/concepts/graph_components.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,5 +39,5 @@
     /// \note This class is a template class so that we can use it to
     /// create graph skeleton classes. The reason for this is that \c Node
-    /// and \c Arc (or \c Edge) types should \e not derive from the same 
+    /// and \c Arc (or \c Edge) types should \e not derive from the same
     /// base class. For \c Node you should instantiate it with character
     /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
@@ -90,5 +90,5 @@
       ///
       /// This operator defines an ordering of the items.
-      /// It makes possible to use graph item types as key types in 
+      /// It makes possible to use graph item types as key types in
       /// associative containers (e.g. \c std::map).
       ///
@@ -123,5 +123,5 @@
     /// This class describes the base interface of directed graph types.
     /// All digraph %concepts have to conform to this class.
-    /// It just provides types for nodes and arcs and functions 
+    /// It just provides types for nodes and arcs and functions
     /// to get the source and the target nodes of arcs.
     class BaseDigraphComponent {
@@ -427,5 +427,5 @@
     /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
     ///
-    /// This class describes the concept of \c NodeIt, \c ArcIt and 
+    /// This class describes the concept of \c NodeIt, \c ArcIt and
     /// \c EdgeIt subtypes of digraph and graph types.
     template <typename GR, typename Item>
@@ -467,5 +467,5 @@
       /// next item.
       GraphItemIt& operator++() { return *this; }
- 
+
       /// \brief Equality operator
       ///
@@ -502,13 +502,13 @@
     };
 
-    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
+    /// \brief Concept class for \c InArcIt, \c OutArcIt and
     /// \c IncEdgeIt types.
     ///
-    /// This class describes the concept of \c InArcIt, \c OutArcIt 
+    /// This class describes the concept of \c InArcIt, \c OutArcIt
     /// and \c IncEdgeIt subtypes of digraph and graph types.
     ///
     /// \note Since these iterator classes do not inherit from the same
     /// base class, there is an additional template parameter (selector)
-    /// \c sel. For \c InArcIt you should instantiate it with character 
+    /// \c sel. For \c InArcIt you should instantiate it with character
     /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
     template <typename GR,
@@ -531,8 +531,8 @@
       GraphIncIt(const GraphIncIt& it) : Item(it) {}
 
-      /// \brief Constructor that sets the iterator to the first 
+      /// \brief Constructor that sets the iterator to the first
       /// incoming or outgoing arc.
       ///
-      /// Constructor that sets the iterator to the first arc 
+      /// Constructor that sets the iterator to the first arc
       /// incoming to or outgoing from the given node.
       explicit GraphIncIt(const GR&, const Base&) {}
@@ -805,7 +805,7 @@
       /// \brief Return the first edge incident to the given node.
       ///
-      /// This function gives back the first edge incident to the given 
+      /// This function gives back the first edge incident to the given
       /// node. The bool parameter gives back the direction for which the
-      /// source node of the directed arc representing the edge is the 
+      /// source node of the directed arc representing the edge is the
       /// given node.
       void firstInc(Edge&, bool&, const Node&) const {}
@@ -814,5 +814,5 @@
       /// given node.
       ///
-      /// This function gives back the next edge incident to the given 
+      /// This function gives back the next edge incident to the given
       /// node. The bool parameter should be used as \c firstInc() use it.
       void nextInc(Edge&, bool&) const {}
@@ -991,5 +991,5 @@
     ///
     /// This class describes the concept of standard graph maps, i.e.
-    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 
+    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
     /// graph types, which can be used for associating data to graph items.
     /// The standard graph maps must conform to the ReferenceMap concept.
@@ -1046,5 +1046,5 @@
           _Map m1(g);
           _Map m2(g,t);
-          
+
           // Copy constructor
           // _Map m3(m);
@@ -1069,5 +1069,5 @@
     ///
     /// This class describes the interface of mappable directed graphs.
-    /// It extends \ref BaseDigraphComponent with the standard digraph 
+    /// It extends \ref BaseDigraphComponent with the standard digraph
     /// map classes, namely \c NodeMap and \c ArcMap.
     /// This concept is part of the Digraph concept.
@@ -1206,5 +1206,5 @@
     ///
     /// This class describes the interface of mappable undirected graphs.
-    /// It extends \ref MappableDigraphComponent with the standard graph 
+    /// It extends \ref MappableDigraphComponent with the standard graph
     /// map class for edges (\c EdgeMap).
     /// This concept is part of the Graph concept.
@@ -1291,5 +1291,5 @@
     ///
     /// This class describes the interface of extendable directed graphs.
-    /// It extends \ref BaseDigraphComponent with functions for adding 
+    /// It extends \ref BaseDigraphComponent with functions for adding
     /// nodes and arcs to the digraph.
     /// This concept requires \ref AlterableDigraphComponent.
@@ -1335,5 +1335,5 @@
     ///
     /// This class describes the interface of extendable undirected graphs.
-    /// It extends \ref BaseGraphComponent with functions for adding 
+    /// It extends \ref BaseGraphComponent with functions for adding
     /// nodes and edges to the graph.
     /// This concept requires \ref AlterableGraphComponent.
@@ -1379,5 +1379,5 @@
     ///
     /// This class describes the interface of erasable directed graphs.
-    /// It extends \ref BaseDigraphComponent with functions for removing 
+    /// It extends \ref BaseDigraphComponent with functions for removing
     /// nodes and arcs from the digraph.
     /// This concept requires \ref AlterableDigraphComponent.
@@ -1392,5 +1392,5 @@
       /// \brief Erase a node from the digraph.
       ///
-      /// This function erases the given node from the digraph and all arcs 
+      /// This function erases the given node from the digraph and all arcs
       /// connected to the node.
       void erase(const Node&) {}
@@ -1418,5 +1418,5 @@
     ///
     /// This class describes the interface of erasable undirected graphs.
-    /// It extends \ref BaseGraphComponent with functions for removing 
+    /// It extends \ref BaseGraphComponent with functions for removing
     /// nodes and edges from the graph.
     /// This concept requires \ref AlterableGraphComponent.
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 883)
+++ lemon/concepts/heap.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -93,5 +93,5 @@
 #else
       explicit Heap(ItemIntMap&) {}
-#endif      
+#endif
 
       /// \brief Constructor.
@@ -107,5 +107,5 @@
 #else
       explicit Heap(ItemIntMap&, const CMP&) {}
-#endif      
+#endif
 
       /// \brief The number of items stored in the heap.
@@ -139,5 +139,5 @@
 #else
       void push(const Item&, const Prio&) {}
-#endif      
+#endif
 
       /// \brief Return the item having minimum priority.
@@ -169,5 +169,5 @@
 #else
       void erase(const Item&) {}
-#endif      
+#endif
 
       /// \brief The priority of the given item.
@@ -180,5 +180,5 @@
 #else
       Prio operator[](const Item&) const { return Prio(); }
-#endif      
+#endif
 
       /// \brief Set the priority of an item or insert it, if it is
@@ -195,5 +195,5 @@
 #else
       void set(const Item&, const Prio&) {}
-#endif      
+#endif
 
       /// \brief Decrease the priority of an item to the given value.
@@ -207,5 +207,5 @@
 #else
       void decrease(const Item&, const Prio&) {}
-#endif      
+#endif
 
       /// \brief Increase the priority of an item to the given value.
@@ -219,5 +219,5 @@
 #else
       void increase(const Item&, const Prio&) {}
-#endif      
+#endif
 
       /// \brief Return the state of an item.
@@ -233,5 +233,5 @@
 #else
       State state(const Item&) const { return PRE_HEAP; }
-#endif      
+#endif
 
       /// \brief Set the state of an item in the heap.
@@ -246,5 +246,5 @@
 #else
       void state(const Item&, State) {}
-#endif      
+#endif
 
 
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 695)
+++ lemon/connectivity.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -259,5 +259,5 @@
   /// \return \c true if the digraph is strongly connected.
   /// \note By definition, the empty digraph is strongly connected.
-  /// 
+  ///
   /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
   /// \see connected()
@@ -311,5 +311,5 @@
   /// \ingroup graph_properties
   ///
-  /// \brief Count the number of strongly connected components of a 
+  /// \brief Count the number of strongly connected components of a
   /// directed graph
   ///
@@ -745,5 +745,5 @@
   /// \brief Check whether an undirected graph is bi-node-connected.
   ///
-  /// This function checks whether the given undirected graph is 
+  /// This function checks whether the given undirected graph is
   /// bi-node-connected, i.e. any two edges are on same circle.
   ///
@@ -759,5 +759,5 @@
   /// \ingroup graph_properties
   ///
-  /// \brief Count the number of bi-node-connected components of an 
+  /// \brief Count the number of bi-node-connected components of an
   /// undirected graph.
   ///
@@ -813,5 +813,5 @@
   /// \retval compMap A writable edge map. The values will be set from 0
   /// to the number of the bi-node-connected components minus one. Each
-  /// value of the map will be set exactly once, and the values of a 
+  /// value of the map will be set exactly once, and the values of a
   /// certain component will be set continuously.
   /// \return The number of bi-node-connected components.
@@ -859,5 +859,5 @@
   ///
   /// \param graph The undirected graph.
-  /// \retval cutMap A writable node map. The values will be set to 
+  /// \retval cutMap A writable node map. The values will be set to
   /// \c true for the nodes that separate two or more components
   /// (exactly once for each cut node), and will not be changed for
@@ -1086,5 +1086,5 @@
   /// \brief Check whether an undirected graph is bi-edge-connected.
   ///
-  /// This function checks whether the given undirected graph is 
+  /// This function checks whether the given undirected graph is
   /// bi-edge-connected, i.e. any two nodes are connected with at least
   /// two edge-disjoint paths.
@@ -1193,5 +1193,5 @@
   ///
   /// This function finds the bi-edge-connected cut edges in the given
-  /// undirected graph. 
+  /// undirected graph.
   ///
   /// The bi-edge-connected components are the classes of an equivalence
@@ -1350,5 +1350,5 @@
   /// \param digraph The digraph.
   /// \retval order A readable and writable node map. The values will be
-  /// set from 0 to the number of the nodes in the digraph minus one. 
+  /// set from 0 to the number of the nodes in the digraph minus one.
   /// Each value of the map will be set exactly once, and the values will
   /// be set descending order.
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 718)
+++ lemon/core.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1240,5 +1240,6 @@
   protected:
 
-    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
+    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
+    {
       typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
 
@@ -1279,5 +1280,5 @@
     };
 
-  protected: 
+  protected:
 
     const Digraph &_g;
Index: lemon/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 899)
+++ lemon/cost_scaling.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -93,5 +93,5 @@
   /// push/augment and relabel operations for finding a \ref min_cost_flow
   /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
-  /// \ref goldberg97efficient, \ref bunnagel98efficient. 
+  /// \ref goldberg97efficient, \ref bunnagel98efficient.
   /// It is a highly efficient primal-dual solution method, which
   /// can be viewed as the generalization of the \ref Preflow
@@ -190,5 +190,5 @@
       /// paths from a node with excess to a node with deficit.
       AUGMENT,
-      /// Partial augment operations are used, i.e. flow is moved on 
+      /// Partial augment operations are used, i.e. flow is moved on
       /// admissible paths started from a node with excess, but the
       /// lengths of these paths are limited. This method can be viewed
@@ -202,11 +202,12 @@
 
     typedef std::vector<int> IntVector;
-    typedef std::vector<char> BoolVector;
     typedef std::vector<Value> ValueVector;
     typedef std::vector<Cost> CostVector;
     typedef std::vector<LargeCost> LargeCostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
 
   private:
-  
+
     template <typename KT, typename VT>
     class StaticVectorMap {
@@ -214,7 +215,7 @@
       typedef KT Key;
       typedef VT Value;
-      
+
       StaticVectorMap(std::vector<Value>& v) : _v(v) {}
-      
+
       const Value& operator[](const Key& key) const {
         return _v[StaticDigraph::id(key)];
@@ -224,5 +225,5 @@
         return _v[StaticDigraph::id(key)];
       }
-      
+
       void set(const Key& key, const Value& val) {
         _v[StaticDigraph::id(key)] = val;
@@ -249,4 +250,5 @@
     bool _have_lower;
     Value _sum_supply;
+    int _sup_node_num;
 
     // Data structures for storing the digraph
@@ -277,4 +279,10 @@
     int _alpha;
 
+    IntVector _buckets;
+    IntVector _bucket_next;
+    IntVector _bucket_prev;
+    IntVector _rank;
+    int _max_rank;
+
     // Data for a StaticDigraph structure
     typedef std::pair<int, int> IntPair;
@@ -284,7 +292,7 @@
     LargeCostArcMap _cost_map;
     LargeCostNodeMap _pi_map;
-  
+
   public:
-  
+
     /// \brief Constant for infinite upper bounds (capacities).
     ///
@@ -317,4 +325,8 @@
 
     /// @}
+
+  protected:
+
+    CostScaling() {}
 
   public:
@@ -337,5 +349,5 @@
       LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
         "The cost type of CostScaling must be signed");
-      
+
       // Reset data structures
       reset();
@@ -453,5 +465,5 @@
       return *this;
     }
-    
+
     /// @}
 
@@ -555,5 +567,5 @@
         _scost[j] = 0;
         _scost[_reverse[j]] = 0;
-      }      
+      }
       _have_lower = false;
       return *this;
@@ -590,5 +602,5 @@
       _scost.resize(_res_arc_num);
       _supply.resize(_res_node_num);
-      
+
       _res_cap.resize(_res_arc_num);
       _cost.resize(_res_arc_num);
@@ -638,5 +650,5 @@
         _reverse[bi] = fi;
       }
-      
+
       // Reset parameters
       resetParams();
@@ -747,5 +759,5 @@
       }
       if (_sum_supply > 0) return INFEASIBLE;
-      
+
 
       // Initialize vectors
@@ -754,5 +766,5 @@
         _excess[i] = _supply[i];
       }
-      
+
       // Remove infinite upper bounds and check negative arcs
       const Value MAX = std::numeric_limits<Value>::max();
@@ -829,4 +841,9 @@
       }
 
+      _sup_node_num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (sup[n] > 0) ++_sup_node_num;
+      }
+
       // Find a feasible flow using Circulation
       Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
@@ -863,5 +880,5 @@
         for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
           int ra = _reverse[a];
-          _res_cap[a] = 1;
+          _res_cap[a] = 0;
           _res_cap[ra] = 0;
           _cost[a] = 0;
@@ -869,5 +886,5 @@
         }
       }
-      
+
       return OPTIMAL;
     }
@@ -877,5 +894,12 @@
       // Maximum path length for partial augment
       const int MAX_PATH_LENGTH = 4;
-      
+
+      // Initialize data structures for buckets
+      _max_rank = _alpha * _res_node_num;
+      _buckets.resize(_max_rank);
+      _bucket_next.resize(_res_node_num + 1);
+      _bucket_prev.resize(_res_node_num + 1);
+      _rank.resize(_res_node_num + 1);
+
       // Execute the algorithm
       switch (method) {
@@ -917,59 +941,171 @@
     }
 
+    // Initialize a cost scaling phase
+    void initPhase() {
+      // Saturate arcs not satisfying the optimality condition
+      for (int u = 0; u != _res_node_num; ++u) {
+        int last_out = _first_out[u+1];
+        LargeCost pi_u = _pi[u];
+        for (int a = _first_out[u]; a != last_out; ++a) {
+          int v = _target[a];
+          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
+            Value delta = _res_cap[a];
+            _excess[u] -= delta;
+            _excess[v] += delta;
+            _res_cap[a] = 0;
+            _res_cap[_reverse[a]] += delta;
+          }
+        }
+      }
+
+      // Find active nodes (i.e. nodes with positive excess)
+      for (int u = 0; u != _res_node_num; ++u) {
+        if (_excess[u] > 0) _active_nodes.push_back(u);
+      }
+
+      // Initialize the next arcs
+      for (int u = 0; u != _res_node_num; ++u) {
+        _next_out[u] = _first_out[u];
+      }
+    }
+
+    // Early termination heuristic
+    bool earlyTermination() {
+      const double EARLY_TERM_FACTOR = 3.0;
+
+      // Build a static residual graph
+      _arc_vec.clear();
+      _cost_vec.clear();
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_res_cap[j] > 0) {
+          _arc_vec.push_back(IntPair(_source[j], _target[j]));
+          _cost_vec.push_back(_cost[j] + 1);
+        }
+      }
+      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
+
+      // Run Bellman-Ford algorithm to check if the current flow is optimal
+      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
+      bf.init(0);
+      bool done = false;
+      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
+      for (int i = 0; i < K && !done; ++i) {
+        done = bf.processNextWeakRound();
+      }
+      return done;
+    }
+
+    // Global potential update heuristic
+    void globalUpdate() {
+      int bucket_end = _root + 1;
+
+      // Initialize buckets
+      for (int r = 0; r != _max_rank; ++r) {
+        _buckets[r] = bucket_end;
+      }
+      Value total_excess = 0;
+      for (int i = 0; i != _res_node_num; ++i) {
+        if (_excess[i] < 0) {
+          _rank[i] = 0;
+          _bucket_next[i] = _buckets[0];
+          _bucket_prev[_buckets[0]] = i;
+          _buckets[0] = i;
+        } else {
+          total_excess += _excess[i];
+          _rank[i] = _max_rank;
+        }
+      }
+      if (total_excess == 0) return;
+
+      // Search the buckets
+      int r = 0;
+      for ( ; r != _max_rank; ++r) {
+        while (_buckets[r] != bucket_end) {
+          // Remove the first node from the current bucket
+          int u = _buckets[r];
+          _buckets[r] = _bucket_next[u];
+
+          // Search the incomming arcs of u
+          LargeCost pi_u = _pi[u];
+          int last_out = _first_out[u+1];
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            int ra = _reverse[a];
+            if (_res_cap[ra] > 0) {
+              int v = _source[ra];
+              int old_rank_v = _rank[v];
+              if (r < old_rank_v) {
+                // Compute the new rank of v
+                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
+                int new_rank_v = old_rank_v;
+                if (nrc < LargeCost(_max_rank))
+                  new_rank_v = r + 1 + int(nrc);
+
+                // Change the rank of v
+                if (new_rank_v < old_rank_v) {
+                  _rank[v] = new_rank_v;
+                  _next_out[v] = _first_out[v];
+
+                  // Remove v from its old bucket
+                  if (old_rank_v < _max_rank) {
+                    if (_buckets[old_rank_v] == v) {
+                      _buckets[old_rank_v] = _bucket_next[v];
+                    } else {
+                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
+                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
+                    }
+                  }
+
+                  // Insert v to its new bucket
+                  _bucket_next[v] = _buckets[new_rank_v];
+                  _bucket_prev[_buckets[new_rank_v]] = v;
+                  _buckets[new_rank_v] = v;
+                }
+              }
+            }
+          }
+
+          // Finish search if there are no more active nodes
+          if (_excess[u] > 0) {
+            total_excess -= _excess[u];
+            if (total_excess <= 0) break;
+          }
+        }
+        if (total_excess <= 0) break;
+      }
+
+      // Relabel nodes
+      for (int u = 0; u != _res_node_num; ++u) {
+        int k = std::min(_rank[u], r);
+        if (k > 0) {
+          _pi[u] -= _epsilon * k;
+          _next_out[u] = _first_out[u];
+        }
+      }
+    }
+
     /// Execute the algorithm performing augment and relabel operations
     void startAugment(int max_length = std::numeric_limits<int>::max()) {
       // Paramters for heuristics
-      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
-      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
+      const int EARLY_TERM_EPSILON_LIMIT = 1000;
+      const double GLOBAL_UPDATE_FACTOR = 3.0;
+
+      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_update_limit = global_update_freq;
+
+      int relabel_cnt = 0;
 
       // Perform cost scaling phases
-      IntVector pred_arc(_res_node_num);
-      std::vector<int> path_nodes;
+      std::vector<int> path;
       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
                                         1 : _epsilon / _alpha )
       {
-        // "Early Termination" heuristic: use Bellman-Ford algorithm
-        // to check if the current flow is optimal
-        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
-          _arc_vec.clear();
-          _cost_vec.clear();
-          for (int j = 0; j != _res_arc_num; ++j) {
-            if (_res_cap[j] > 0) {
-              _arc_vec.push_back(IntPair(_source[j], _target[j]));
-              _cost_vec.push_back(_cost[j] + 1);
-            }
-          }
-          _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
-
-          BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
-          bf.init(0);
-          bool done = false;
-          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
-          for (int i = 0; i < K && !done; ++i)
-            done = bf.processNextWeakRound();
-          if (done) break;
-        }
-
-        // Saturate arcs not satisfying the optimality condition
-        for (int a = 0; a != _res_arc_num; ++a) {
-          if (_res_cap[a] > 0 &&
-              _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
-            Value delta = _res_cap[a];
-            _excess[_source[a]] -= delta;
-            _excess[_target[a]] += delta;
-            _res_cap[a] = 0;
-            _res_cap[_reverse[a]] += delta;
-          }
-        }
-        
-        // Find active nodes (i.e. nodes with positive excess)
-        for (int u = 0; u != _res_node_num; ++u) {
-          if (_excess[u] > 0) _active_nodes.push_back(u);
-        }
-
-        // Initialize the next arcs
-        for (int u = 0; u != _res_node_num; ++u) {
-          _next_out[u] = _first_out[u];
-        }
+        // Early termination heuristic
+        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
+          if (earlyTermination()) break;
+        }
+
+        // Initialize current phase
+        initPhase();
 
         // Perform partial augment and relabel operations
@@ -982,23 +1118,18 @@
           if (_active_nodes.size() == 0) break;
           int start = _active_nodes.front();
-          path_nodes.clear();
-          path_nodes.push_back(start);
 
           // Find an augmenting path from the start node
+          path.clear();
           int tip = start;
-          while (_excess[tip] >= 0 &&
-                 int(path_nodes.size()) <= max_length) {
+          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
             int u;
-            LargeCost min_red_cost, rc;
-            int last_out = _sum_supply < 0 ?
-              _first_out[tip+1] : _first_out[tip+1] - 1;
+            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
+            int last_out = _first_out[tip+1];
             for (int a = _next_out[tip]; a != last_out; ++a) {
-              if (_res_cap[a] > 0 &&
-                  _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
-                u = _target[a];
-                pred_arc[u] = a;
+              u = _target[a];
+              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
+                path.push_back(a);
                 _next_out[tip] = a;
                 tip = u;
-                path_nodes.push_back(tip);
                 goto next_step;
               }
@@ -1006,7 +1137,11 @@
 
             // Relabel tip node
-            min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
+            min_red_cost = std::numeric_limits<LargeCost>::max();
+            if (tip != start) {
+              int ra = _reverse[path.back()];
+              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
+            }
             for (int a = _first_out[tip]; a != last_out; ++a) {
-              rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
+              rc = _cost[a] + pi_tip - _pi[_target[a]];
               if (_res_cap[a] > 0 && rc < min_red_cost) {
                 min_red_cost = rc;
@@ -1014,12 +1149,11 @@
             }
             _pi[tip] -= min_red_cost + _epsilon;
-
-            // Reset the next arc of tip
             _next_out[tip] = _first_out[tip];
+            ++relabel_cnt;
 
             // Step back
             if (tip != start) {
-              path_nodes.pop_back();
-              tip = path_nodes.back();
+              tip = _source[path.back()];
+              path.pop_back();
             }
 
@@ -1029,9 +1163,9 @@
           // Augment along the found path (as much flow as possible)
           Value delta;
-          int u, v = path_nodes.front(), pa;
-          for (int i = 1; i < int(path_nodes.size()); ++i) {
+          int pa, u, v = start;
+          for (int i = 0; i != int(path.size()); ++i) {
+            pa = path[i];
             u = v;
-            v = path_nodes[i];
-            pa = pred_arc[v];
+            v = _target[pa];
             delta = std::min(_res_cap[pa], _excess[u]);
             _res_cap[pa] -= delta;
@@ -1042,4 +1176,10 @@
               _active_nodes.push_back(v);
           }
+
+          // Global update heuristic
+          if (relabel_cnt >= next_update_limit) {
+            globalUpdate();
+            next_update_limit += global_update_freq;
+          }
         }
       }
@@ -1049,67 +1189,38 @@
     void startPush() {
       // Paramters for heuristics
-      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
-      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
+      const int EARLY_TERM_EPSILON_LIMIT = 1000;
+      const double GLOBAL_UPDATE_FACTOR = 2.0;
+
+      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_update_limit = global_update_freq;
+
+      int relabel_cnt = 0;
 
       // Perform cost scaling phases
       BoolVector hyper(_res_node_num, false);
+      LargeCostVector hyper_cost(_res_node_num);
       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
                                         1 : _epsilon / _alpha )
       {
-        // "Early Termination" heuristic: use Bellman-Ford algorithm
-        // to check if the current flow is optimal
-        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
-          _arc_vec.clear();
-          _cost_vec.clear();
-          for (int j = 0; j != _res_arc_num; ++j) {
-            if (_res_cap[j] > 0) {
-              _arc_vec.push_back(IntPair(_source[j], _target[j]));
-              _cost_vec.push_back(_cost[j] + 1);
-            }
-          }
-          _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
-
-          BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
-          bf.init(0);
-          bool done = false;
-          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
-          for (int i = 0; i < K && !done; ++i)
-            done = bf.processNextWeakRound();
-          if (done) break;
-        }
-
-        // Saturate arcs not satisfying the optimality condition
-        for (int a = 0; a != _res_arc_num; ++a) {
-          if (_res_cap[a] > 0 &&
-              _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
-            Value delta = _res_cap[a];
-            _excess[_source[a]] -= delta;
-            _excess[_target[a]] += delta;
-            _res_cap[a] = 0;
-            _res_cap[_reverse[a]] += delta;
-          }
-        }
-
-        // Find active nodes (i.e. nodes with positive excess)
-        for (int u = 0; u != _res_node_num; ++u) {
-          if (_excess[u] > 0) _active_nodes.push_back(u);
-        }
-
-        // Initialize the next arcs
-        for (int u = 0; u != _res_node_num; ++u) {
-          _next_out[u] = _first_out[u];
-        }
+        // Early termination heuristic
+        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
+          if (earlyTermination()) break;
+        }
+
+        // Initialize current phase
+        initPhase();
 
         // Perform push and relabel operations
         while (_active_nodes.size() > 0) {
-          LargeCost min_red_cost, rc;
+          LargeCost min_red_cost, rc, pi_n;
           Value delta;
           int n, t, a, last_out = _res_arc_num;
 
+        next_node:
           // Select an active node (FIFO selection)
-        next_node:
           n = _active_nodes.front();
-          last_out = _sum_supply < 0 ?
-            _first_out[n+1] : _first_out[n+1] - 1;
+          last_out = _first_out[n+1];
+          pi_n = _pi[n];
 
           // Perform push operations if there are admissible arcs
@@ -1117,5 +1228,5 @@
             for (a = _next_out[n]; a != last_out; ++a) {
               if (_res_cap[a] > 0 &&
-                  _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
+                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
                 delta = std::min(_res_cap[a], _excess[n]);
                 t = _target[a];
@@ -1123,9 +1234,9 @@
                 // Push-look-ahead heuristic
                 Value ahead = -_excess[t];
-                int last_out_t = _sum_supply < 0 ?
-                  _first_out[t+1] : _first_out[t+1] - 1;
+                int last_out_t = _first_out[t+1];
+                LargeCost pi_t = _pi[t];
                 for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
-                  if (_res_cap[ta] > 0 && 
-                      _cost[ta] + _pi[_source[ta]] - _pi[_target[ta]] < 0)
+                  if (_res_cap[ta] > 0 &&
+                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
                     ahead += _res_cap[ta];
                   if (ahead >= delta) break;
@@ -1134,5 +1245,5 @@
 
                 // Push flow along the arc
-                if (ahead < delta) {
+                if (ahead < delta && !hyper[t]) {
                   _res_cap[a] -= ahead;
                   _res_cap[_reverse[a]] += ahead;
@@ -1141,4 +1252,5 @@
                   _active_nodes.push_front(t);
                   hyper[t] = true;
+                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
                   _next_out[n] = a;
                   goto next_node;
@@ -1163,7 +1275,8 @@
           // Relabel the node if it is still active (or hyper)
           if (_excess[n] > 0 || hyper[n]) {
-            min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
+             min_red_cost = hyper[n] ? -hyper_cost[n] :
+               std::numeric_limits<LargeCost>::max();
             for (int a = _first_out[n]; a != last_out; ++a) {
-              rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
+              rc = _cost[a] + pi_n - _pi[_target[a]];
               if (_res_cap[a] > 0 && rc < min_red_cost) {
                 min_red_cost = rc;
@@ -1171,10 +1284,9 @@
             }
             _pi[n] -= min_red_cost + _epsilon;
+            _next_out[n] = _first_out[n];
             hyper[n] = false;
-
-            // Reset the next arc
-            _next_out[n] = _first_out[n];
+            ++relabel_cnt;
           }
-        
+
           // Remove nodes that are not active nor hyper
         remove_nodes:
@@ -1184,4 +1296,12 @@
             _active_nodes.pop_front();
           }
+
+          // Global update heuristic
+          if (relabel_cnt >= next_update_limit) {
+            globalUpdate();
+            for (int u = 0; u != _res_node_num; ++u)
+              hyper[u] = false;
+            next_update_limit += global_update_freq;
+          }
         }
       }
Index: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 793)
+++ lemon/cplex.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -112,5 +112,5 @@
   }
 
-  int CplexBase::_addRow(Value lb, ExprIterator b, 
+  int CplexBase::_addRow(Value lb, ExprIterator b,
                          ExprIterator e, Value ub) {
     int i = CPXgetnumrows(cplexEnv(), _prob);
@@ -490,5 +490,5 @@
 
   void CplexBase::_applyMessageLevel() {
-    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
+    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
                    _message_enabled ? CPX_ON : CPX_OFF);
   }
Index: lemon/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 898)
+++ lemon/cycle_canceling.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,5 +35,5 @@
 #include <lemon/circulation.h>
 #include <lemon/bellman_ford.h>
-#include <lemon/howard.h>
+#include <lemon/howard_mmc.h>
 
 namespace lemon {
@@ -143,13 +143,14 @@
 
     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
-    
+
     typedef std::vector<int> IntVector;
-    typedef std::vector<char> CharVector;
     typedef std::vector<double> DoubleVector;
     typedef std::vector<Value> ValueVector;
     typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
 
   private:
-  
+
     template <typename KT, typename VT>
     class StaticVectorMap {
@@ -157,7 +158,7 @@
       typedef KT Key;
       typedef VT Value;
-      
+
       StaticVectorMap(std::vector<Value>& v) : _v(v) {}
-      
+
       const Value& operator[](const Key& key) const {
         return _v[StaticDigraph::id(key)];
@@ -167,5 +168,5 @@
         return _v[StaticDigraph::id(key)];
       }
-      
+
       void set(const Key& key, const Value& val) {
         _v[StaticDigraph::id(key)] = val;
@@ -199,5 +200,5 @@
     IntArcMap _arc_idb;
     IntVector _first_out;
-    CharVector _forward;
+    BoolVector _forward;
     IntVector _source;
     IntVector _target;
@@ -221,7 +222,7 @@
     CostArcMap _cost_map;
     CostNodeMap _pi_map;
-  
+
   public:
-  
+
     /// \brief Constant for infinite upper bounds (capacities).
     ///
@@ -366,5 +367,5 @@
       return *this;
     }
-    
+
     /// @}
 
@@ -466,5 +467,5 @@
         _cost[j] = 0;
         _cost[_reverse[j]] = 0;
-      }      
+      }
       _have_lower = false;
       return *this;
@@ -508,5 +509,5 @@
       _cost.resize(_res_arc_num);
       _supply.resize(_res_node_num);
-      
+
       _res_cap.resize(_res_arc_num);
       _pi.resize(_res_node_num);
@@ -554,5 +555,5 @@
         _reverse[bi] = fi;
       }
-      
+
       // Reset parameters
       resetParams();
@@ -663,5 +664,5 @@
       }
       if (_sum_supply > 0) return INFEASIBLE;
-      
+
 
       // Initialize vectors
@@ -670,5 +671,5 @@
       }
       ValueVector excess(_supply);
-      
+
       // Remove infinite upper bounds and check negative arcs
       const Value MAX = std::numeric_limits<Value>::max();
@@ -770,8 +771,8 @@
         }
       }
-      
+
       return OPTIMAL;
     }
-    
+
     // Build a StaticDigraph structure containing the current
     // residual network
@@ -829,5 +830,5 @@
       const int BF_FIRST_LIMIT  = 2;
       const double BF_LIMIT_FACTOR = 1.5;
-      
+
       typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap;
       typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph;
@@ -836,5 +837,5 @@
         ::template SetDistMap<CostNodeMap>
         ::template SetPredMap<PredMap>::Create BF;
-      
+
       // Build the residual network
       _arc_vec.clear();
@@ -924,12 +925,12 @@
       typedef SimplePath<StaticDigraph> SPath;
       typedef typename SPath::ArcIt SPathArcIt;
-      typedef typename Howard<StaticDigraph, CostArcMap>
+      typedef typename HowardMmc<StaticDigraph, CostArcMap>
         ::template SetPath<SPath>::Create MMC;
-      
+
       SPath cycle;
       MMC mmc(_sgr, _cost_map);
       mmc.cycle(cycle);
       buildResidualNetwork();
-      while (mmc.findMinMean() && mmc.cycleLength() < 0) {
+      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
         // Find the cycle
         mmc.findCycle();
@@ -949,5 +950,5 @@
         }
 
-        // Rebuild the residual network        
+        // Rebuild the residual network
         buildResidualNetwork();
       }
@@ -963,6 +964,6 @@
       DoubleVector pi(_res_node_num, 0.0);
       IntVector level(_res_node_num);
-      CharVector reached(_res_node_num);
-      CharVector processed(_res_node_num);
+      BoolVector reached(_res_node_num);
+      BoolVector processed(_res_node_num);
       IntVector pred_node(_res_node_num);
       IntVector pred_arc(_res_node_num);
@@ -1132,5 +1133,5 @@
           }
         } else {
-          typedef Howard<StaticDigraph, CostArcMap> MMC;
+          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
           typedef typename BellmanFord<StaticDigraph, CostArcMap>
             ::template SetDistMap<CostNodeMap>::Create BF;
@@ -1139,9 +1140,9 @@
           buildResidualNetwork();
           MMC mmc(_sgr, _cost_map);
-          mmc.findMinMean();
+          mmc.findCycleMean();
           epsilon = -mmc.cycleMean();
-          Cost cycle_cost = mmc.cycleLength();
-          int cycle_size = mmc.cycleArcNum();
-          
+          Cost cycle_cost = mmc.cycleCost();
+          int cycle_size = mmc.cycleSize();
+
           // Compute feasible potentials for the current epsilon
           for (int i = 0; i != int(_cost_vec.size()); ++i) {
@@ -1155,5 +1156,5 @@
             pi[u] = static_cast<double>(_pi[u]) / cycle_size;
           }
-        
+
           iter = limit;
         }
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 891)
+++ lemon/dfs.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -83,5 +83,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a \c ReachedMap.
@@ -271,5 +272,6 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ReachedMap type.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
@@ -803,5 +805,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a ReachedMap.
@@ -1208,5 +1211,6 @@
     ///
     /// The type of the map that indicates which nodes are reached.
-    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    /// It must conform to the
+    /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
 
Index: lemon/dheap.h
===================================================================
--- lemon/dheap.h	(revision 929)
+++ lemon/dheap.h	(revision 929)
@@ -0,0 +1,352 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_DHEAP_H
+#define LEMON_DHEAP_H
+
+///\ingroup heaps
+///\file
+///\brief D-ary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief D-ary heap data structure.
+  ///
+  /// This class implements the \e D-ary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The \ref DHeap "D-ary heap" is a generalization of the
+  /// \ref BinHeap "binary heap" structure, its nodes have at most
+  /// \c D children, instead of two.
+  /// \ref BinHeap and \ref QuadHeap are specialized implementations
+  /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam D The degree of the heap, each node have at most \e D
+  /// children. The default is 16. Powers of two are suggested to use
+  /// so that the multiplications and divisions needed to traverse the
+  /// nodes of the heap could be performed faster.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa FouraryHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, int D, typename CMP>
+#else
+  template <typename PR, typename IM, int D = 16,
+            typename CMP = std::less<PR> >
+#endif
+  class DHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit DHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    DHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    int parent(int i) { return (i-1)/D; }
+    int firstChild(int i) { return D*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+D<=length ) {
+          int min=child;
+          for (int i=1; i<D; ++i) {
+            if( less(_data[child+i], _data[min]) )
+              min=child+i;
+          }
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          while (++child < length) {
+            if( less(_data[child], _data[min]) )
+              min=child;
+          }
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx<0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx=_iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first=j;
+    }
+
+  }; // class DHeap
+
+} // namespace lemon
+
+#endif // LEMON_DHEAP_H
Index: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 891)
+++ lemon/dijkstra.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 631)
+++ lemon/dimacs.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -62,5 +62,5 @@
 
   ///This function starts seeking the beginning of the given file for the
-  ///problem type and size info. 
+  ///problem type and size info.
   ///The found data is returned in a special struct that can be evaluated
   ///and passed to the appropriate reader function.
@@ -213,5 +213,5 @@
         std::numeric_limits<Capacity>::infinity() :
         std::numeric_limits<Capacity>::max();
- 
+
     while (is >> c) {
       switch (c) {
@@ -238,5 +238,5 @@
           e = g.addArc(nodes[i], nodes[j]);
           capacity.set(e, _cap);
-        } 
+        }
         else if (desc.type==DimacsDescriptor::MAX) {
           is >> i >> j >> _cap;
@@ -363,9 +363,9 @@
     g.addArc(s,t);
   }
-  
+
   /// \brief DIMACS plain (di)graph reader function.
   ///
   /// This function reads a plain (di)graph without any designated nodes
-  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
+  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
   /// DIMACS files having a line starting with
   /// \code
@@ -393,5 +393,5 @@
       nodes[k] = g.addNode();
     }
-    
+
     while (is >> c) {
       switch (c) {
Index: lemon/edge_set.h
===================================================================
--- lemon/edge_set.h	(revision 834)
+++ lemon/edge_set.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/euler.h
===================================================================
--- lemon/euler.h	(revision 695)
+++ lemon/euler.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -27,5 +27,5 @@
 /// \ingroup graph_properties
 /// \file
-/// \brief Euler tour iterators and a function for checking the \e Eulerian 
+/// \brief Euler tour iterators and a function for checking the \e Eulerian
 /// property.
 ///
@@ -42,5 +42,5 @@
   ///
   ///For example, if the given digraph has an Euler tour (i.e it has only one
-  ///non-trivial component and the in-degree is equal to the out-degree 
+  ///non-trivial component and the in-degree is equal to the out-degree
   ///for all nodes), then the following code will put the arcs of \c g
   ///to the vector \c et according to an Euler tour of \c g.
@@ -139,5 +139,5 @@
   ///and \c Edge types of the graph.
   ///
-  ///For example, if the given graph has an Euler tour (i.e it has only one 
+  ///For example, if the given graph has an Euler tour (i.e it has only one
   ///non-trivial component and the degree of each node is even),
   ///the following code will print the arc IDs according to an
@@ -148,5 +148,5 @@
   ///  }
   ///\endcode
-  ///Although this iterator is for undirected graphs, it still returns 
+  ///Although this iterator is for undirected graphs, it still returns
   ///arcs in order to indicate the direction of the tour.
   ///(But arcs convert to edges, of course.)
@@ -234,5 +234,5 @@
     /// Postfix incrementation.
     ///
-    ///\warning This incrementation returns an \c Arc (which converts to 
+    ///\warning This incrementation returns an \c Arc (which converts to
     ///an \c Edge), not an \ref EulerIt, as one may expect.
     Arc operator++(int)
Index: mon/fourary_heap.h
===================================================================
--- lemon/fourary_heap.h	(revision 753)
+++ 	(revision )
@@ -1,342 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2009
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_FOURARY_HEAP_H
-#define LEMON_FOURARY_HEAP_H
-
-///\ingroup heaps
-///\file
-///\brief Fourary heap implementation.
-
-#include <vector>
-#include <utility>
-#include <functional>
-
-namespace lemon {
-
-  /// \ingroup heaps
-  ///
-  ///\brief Fourary heap data structure.
-  ///
-  /// This class implements the \e fourary \e heap data structure.
-  /// It fully conforms to the \ref concepts::Heap "heap concept".
-  ///
-  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
-  /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
-  /// but its nodes have at most four children, instead of two.
-  ///
-  /// \tparam PR Type of the priorities of the items.
-  /// \tparam IM A read-writable item map with \c int values, used
-  /// internally to handle the cross references.
-  /// \tparam CMP A functor class for comparing the priorities.
-  /// The default is \c std::less<PR>.
-  ///
-  ///\sa BinHeap
-  ///\sa KaryHeap
-#ifdef DOXYGEN
-  template <typename PR, typename IM, typename CMP>
-#else
-  template <typename PR, typename IM, typename CMP = std::less<PR> >
-#endif
-  class FouraryHeap {
-  public:
-    /// Type of the item-int map.
-    typedef IM ItemIntMap;
-    /// Type of the priorities.
-    typedef PR Prio;
-    /// Type of the items stored in the heap.
-    typedef typename ItemIntMap::Key Item;
-    /// Type of the item-priority pairs.
-    typedef std::pair<Item,Prio> Pair;
-    /// Functor type for comparing the priorities.
-    typedef CMP Compare;
-
-    /// \brief Type to represent the states of the items.
-    ///
-    /// Each item has a state associated to it. It can be "in heap",
-    /// "pre-heap" or "post-heap". The latter two are indifferent from the
-    /// heap's point of view, but may be useful to the user.
-    ///
-    /// The item-int map must be initialized in such way that it assigns
-    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
-    enum State {
-      IN_HEAP = 0,    ///< = 0.
-      PRE_HEAP = -1,  ///< = -1.
-      POST_HEAP = -2  ///< = -2.
-    };
-
-  private:
-    std::vector<Pair> _data;
-    Compare _comp;
-    ItemIntMap &_iim;
-
-  public:
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
-
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    /// \param comp The function object used for comparing the priorities.
-    FouraryHeap(ItemIntMap &map, const Compare &comp)
-      : _iim(map), _comp(comp) {}
-
-    /// \brief The number of items stored in the heap.
-    ///
-    /// This function returns the number of items stored in the heap.
-    int size() const { return _data.size(); }
-
-    /// \brief Check if the heap is empty.
-    ///
-    /// This function returns \c true if the heap is empty.
-    bool empty() const { return _data.empty(); }
-
-    /// \brief Make the heap empty.
-    ///
-    /// This functon makes the heap empty.
-    /// It does not change the cross reference map. If you want to reuse
-    /// a heap that is not surely empty, you should first clear it and
-    /// then you should set the cross reference map to \c PRE_HEAP
-    /// for each item.
-    void clear() { _data.clear(); }
-
-  private:
-    static int parent(int i) { return (i-1)/4; }
-    static int firstChild(int i) { return 4*i+1; }
-
-    bool less(const Pair &p1, const Pair &p2) const {
-      return _comp(p1.second, p2.second);
-    }
-
-    void bubbleUp(int hole, Pair p) {
-      int par = parent(hole);
-      while( hole>0 && less(p,_data[par]) ) {
-        move(_data[par],hole);
-        hole = par;
-        par = parent(hole);
-      }
-      move(p, hole);
-    }
-
-    void bubbleDown(int hole, Pair p, int length) {
-      if( length>1 ) {
-        int child = firstChild(hole);
-        while( child+3<length ) {
-          int min=child;
-          if( less(_data[++child], _data[min]) ) min=child;
-          if( less(_data[++child], _data[min]) ) min=child;
-          if( less(_data[++child], _data[min]) ) min=child;
-          if( !less(_data[min], p) )
-            goto ok;
-          move(_data[min], hole);
-          hole = min;
-          child = firstChild(hole);
-        }
-        if ( child<length ) {
-          int min = child;
-          if( ++child<length && less(_data[child], _data[min]) ) min=child;
-          if( ++child<length && less(_data[child], _data[min]) ) min=child;
-          if( less(_data[min], p) ) {
-            move(_data[min], hole);
-            hole = min;
-          }
-        }
-      }
-    ok:
-      move(p, hole);
-    }
-
-    void move(const Pair &p, int i) {
-      _data[i] = p;
-      _iim.set(p.first, i);
-    }
-
-  public:
-    /// \brief Insert a pair of item and priority into the heap.
-    ///
-    /// This function inserts \c p.first to the heap with priority
-    /// \c p.second.
-    /// \param p The pair to insert.
-    /// \pre \c p.first must not be stored in the heap.
-    void push(const Pair &p) {
-      int n = _data.size();
-      _data.resize(n+1);
-      bubbleUp(n, p);
-    }
-
-    /// \brief Insert an item into the heap with the given priority.
-    ///
-    /// This function inserts the given item into the heap with the
-    /// given priority.
-    /// \param i The item to insert.
-    /// \param p The priority of the item.
-    /// \pre \e i must not be stored in the heap.
-    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
-
-    /// \brief Return the item having minimum priority.
-    ///
-    /// This function returns the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    Item top() const { return _data[0].first; }
-
-    /// \brief The minimum priority.
-    ///
-    /// This function returns the minimum priority.
-    /// \pre The heap must be non-empty.
-    Prio prio() const { return _data[0].second; }
-
-    /// \brief Remove the item having minimum priority.
-    ///
-    /// This function removes the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    void pop() {
-      int n = _data.size()-1;
-      _iim.set(_data[0].first, POST_HEAP);
-      if (n>0) bubbleDown(0, _data[n], n);
-      _data.pop_back();
-    }
-
-    /// \brief Remove the given item from the heap.
-    ///
-    /// This function removes the given item from the heap if it is
-    /// already stored.
-    /// \param i The item to delete.
-    /// \pre \e i must be in the heap.
-    void erase(const Item &i) {
-      int h = _iim[i];
-      int n = _data.size()-1;
-      _iim.set(_data[h].first, POST_HEAP);
-      if( h<n ) {
-        if( less(_data[parent(h)], _data[n]) )
-          bubbleDown(h, _data[n], n);
-        else
-          bubbleUp(h, _data[n]);
-      }
-      _data.pop_back();
-    }
-
-    /// \brief The priority of the given item.
-    ///
-    /// This function returns the priority of the given item.
-    /// \param i The item.
-    /// \pre \e i must be in the heap.
-    Prio operator[](const Item &i) const {
-      int idx = _iim[i];
-      return _data[idx].second;
-    }
-
-    /// \brief Set the priority of an item or insert it, if it is
-    /// not stored in the heap.
-    ///
-    /// This method sets the priority of the given item if it is
-    /// already stored in the heap. Otherwise it inserts the given
-    /// item into the heap with the given priority.
-    /// \param i The item.
-    /// \param p The priority.
-    void set(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      if( idx < 0 )
-        push(i,p);
-      else if( _comp(p, _data[idx].second) )
-        bubbleUp(idx, Pair(i,p));
-      else
-        bubbleDown(idx, Pair(i,p), _data.size());
-    }
-
-    /// \brief Decrease the priority of an item to the given value.
-    ///
-    /// This function decreases the priority of an item to the given value.
-    /// \param i The item.
-    /// \param p The priority.
-    /// \pre \e i must be stored in the heap with priority at least \e p.
-    void decrease(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      bubbleUp(idx, Pair(i,p));
-    }
-
-    /// \brief Increase the priority of an item to the given value.
-    ///
-    /// This function increases the priority of an item to the given value.
-    /// \param i The item.
-    /// \param p The priority.
-    /// \pre \e i must be stored in the heap with priority at most \e p.
-    void increase(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      bubbleDown(idx, Pair(i,p), _data.size());
-    }
-
-    /// \brief Return the state of an item.
-    ///
-    /// This method returns \c PRE_HEAP if the given item has never
-    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
-    /// and \c POST_HEAP otherwise.
-    /// In the latter case it is possible that the item will get back
-    /// to the heap again.
-    /// \param i The item.
-    State state(const Item &i) const {
-      int s = _iim[i];
-      if (s>=0) s=0;
-      return State(s);
-    }
-
-    /// \brief Set the state of an item in the heap.
-    ///
-    /// This function sets the state of the given item in the heap.
-    /// It can be used to manually clear the heap when it is important
-    /// to achive better time complexity.
-    /// \param i The item.
-    /// \param st The state. It should not be \c IN_HEAP.
-    void state(const Item& i, State st) {
-      switch (st) {
-        case POST_HEAP:
-        case PRE_HEAP:
-          if (state(i) == IN_HEAP) erase(i);
-          _iim[i] = st;
-          break;
-        case IN_HEAP:
-          break;
-      }
-    }
-
-    /// \brief Replace an item in the heap.
-    ///
-    /// This function replaces item \c i with item \c j.
-    /// Item \c i must be in the heap, while \c j must be out of the heap.
-    /// After calling this method, item \c i will be out of the
-    /// heap and \c j will be in the heap with the same prioriority
-    /// as item \c i had before.
-    void replace(const Item& i, const Item& j) {
-      int idx = _iim[i];
-      _iim.set(i, _iim[j]);
-      _iim.set(j, idx);
-      _data[idx].first = j;
-    }
-
-  }; // class FouraryHeap
-
-} // namespace lemon
-
-#endif // LEMON_FOURARY_HEAP_H
Index: lemon/fractional_matching.h
===================================================================
--- lemon/fractional_matching.h	(revision 956)
+++ lemon/fractional_matching.h	(revision 956)
@@ -0,0 +1,2139 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_FRACTIONAL_MATCHING_H
+#define LEMON_FRACTIONAL_MATCHING_H
+
+#include <vector>
+#include <queue>
+#include <set>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/unionfind.h>
+#include <lemon/bin_heap.h>
+#include <lemon/maps.h>
+#include <lemon/assert.h>
+#include <lemon/elevator.h>
+
+///\ingroup matching
+///\file
+///\brief Fractional matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \brief Default traits class of MaxFractionalMatching class.
+  ///
+  /// Default traits class of MaxFractionalMatching class.
+  /// \tparam GR Graph type.
+  template <typename GR>
+  struct MaxFractionalMatchingDefaultTraits {
+
+    /// \brief The type of the graph the algorithm runs on.
+    typedef GR Graph;
+
+    /// \brief The type of the map that stores the matching.
+    ///
+    /// The type of the map that stores the matching arcs.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
+
+    /// \brief Instantiates a MatchingMap.
+    ///
+    /// This function instantiates a \ref MatchingMap.
+    /// \param graph The graph for which we would like to define
+    /// the matching map.
+    static MatchingMap* createMatchingMap(const Graph& graph) {
+      return new MatchingMap(graph);
+    }
+
+    /// \brief The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// \sa Elevator
+    /// \sa LinkedElevator
+    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param graph The graph for which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Graph& graph, int max_level) {
+      return new Elevator(graph, max_level);
+    }
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Max cardinality fractional matching
+  ///
+  /// This class provides an implementation of fractional matching
+  /// algorithm based on push-relabel principle.
+  ///
+  /// The maximum cardinality fractional matching is a relaxation of the
+  /// maximum cardinality matching problem where the odd set constraints
+  /// are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result can be represented as the union of a
+  /// matching with one value edges and a set of odd length cycles
+  /// with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// barrier. The number of adjacents of any node set minus the size
+  /// of node set is a lower bound on the uncovered nodes in the
+  /// graph. For maximum matching a barrier is computed which
+  /// maximizes this difference.
+  ///
+  /// The algorithm can be executed with the run() function.  After it
+  /// the matching (the primal solution) and the barrier (the dual
+  /// solution) can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxFractionalMatching::primalScale "2".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+#ifdef DOXYGEN
+  template <typename GR, typename TR>
+#else
+  template <typename GR,
+            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
+#endif
+  class MaxFractionalMatching {
+  public:
+
+    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
+    /// class" of the algorithm.
+    typedef TR Traits;
+    /// The type of the graph the algorithm runs on.
+    typedef typename TR::Graph Graph;
+    /// The type of the matching map.
+    typedef typename TR::MatchingMap MatchingMap;
+    /// The type of the elevator.
+    typedef typename TR::Elevator Elevator;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+  private:
+
+    const Graph &_graph;
+    int _node_num;
+    bool _allow_loops;
+    int _empty_level;
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    bool _local_matching;
+    MatchingMap *_matching;
+
+    bool _local_level;
+    Elevator *_level;
+
+    typedef typename Graph::template NodeMap<int> InDegMap;
+    InDegMap *_indeg;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _local_matching = true;
+        _matching = Traits::createMatchingMap(_graph);
+      }
+      if (!_level) {
+        _local_level = true;
+        _level = Traits::createElevator(_graph, _node_num);
+      }
+      if (!_indeg) {
+        _indeg = new InDegMap(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_matching) {
+        delete _matching;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_indeg) {
+        delete _indeg;
+      }
+    }
+
+    void postprocessing() {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 0) continue;
+        _indeg->set(n, -1);
+        Node u = n;
+        while ((*_matching)[u] != INVALID) {
+          Node v = _graph.target((*_matching)[u]);
+          _indeg->set(v, -1);
+          Arc a = _graph.oppositeArc((*_matching)[u]);
+          u = _graph.target((*_matching)[v]);
+          _indeg->set(u, -1);
+          _matching->set(v, a);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 1) continue;
+        _indeg->set(n, -1);
+
+        int num = 1;
+        Node u = _graph.target((*_matching)[n]);
+        while (u != n) {
+          _indeg->set(u, -1);
+          u = _graph.target((*_matching)[u]);
+          ++num;
+        }
+        if (num % 2 == 0 && num > 2) {
+          Arc prev = _graph.oppositeArc((*_matching)[n]);
+          Node v = _graph.target((*_matching)[n]);
+          u = _graph.target((*_matching)[v]);
+          _matching->set(v, prev);
+          while (u != n) {
+            prev = _graph.oppositeArc((*_matching)[u]);
+            v = _graph.target((*_matching)[u]);
+            u = _graph.target((*_matching)[v]);
+            _matching->set(v, prev);
+          }
+        }
+      }
+    }
+
+  public:
+
+    typedef MaxFractionalMatching Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetMatchingMapTraits : public Traits {
+      typedef T MatchingMap;
+      static MatchingMap *createMatchingMap(const Graph&) {
+        LEMON_ASSERT(false, "MatchingMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// MatchingMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting MatchingMap
+    /// type.
+    template <typename T>
+    struct SetMatchingMap
+      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename T>
+    struct SetElevator
+      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph& graph, int max_level) {
+        return new Elevator(graph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// graph and the maximum level should be passed to it).
+    /// However an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename T>
+    struct SetStandardElevator
+      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph,
+                                    SetStandardElevatorTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    MaxFractionalMatching() {}
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    ///
+    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
+      : _graph(graph), _allow_loops(allow_loops),
+        _local_matching(false), _matching(0),
+        _local_level(false), _level(0),  _indeg(0)
+    {}
+
+    ~MaxFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the matching map.
+    ///
+    /// Sets the matching map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    MaxFractionalMatching& matchingMap(MatchingMap& map) {
+      if (_local_matching) {
+        delete _matching;
+        _local_matching = false;
+      }
+      _matching = &map;
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    MaxFractionalMatching& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use one of the
+    /// member functions called \c run(). \n
+    /// If you need more control on the execution, first
+    /// you must call \ref init() and then one variant of the start()
+    /// member.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// matching.
+    void init() {
+      createStructures();
+
+      _level->initStart();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _indeg->set(n, 0);
+        _matching->set(n, INVALID);
+        _level->initAddItem(n);
+      }
+      _level->initFinish();
+
+      _empty_level = _node_num;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+          if (_graph.target(a) == n && !_allow_loops) continue;
+          _matching->set(n, a);
+          Node v = _graph.target((*_matching)[n]);
+          _indeg->set(v, (*_indeg)[v] + 1);
+          break;
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] == 0) {
+          _level->activate(n);
+        }
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a fractional matching
+    ///
+    /// The algorithm computes a maximum fractional matching.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    void start(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+        }
+      no_more_push:
+        ;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] == INVALID) continue;
+        Node u = _graph.target((*_matching)[n]);
+        if ((*_indeg)[u] > 1) {
+          _indeg->set(u, (*_indeg)[u] - 1);
+          _matching->set(n, INVALID);
+        }
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a perfect fractional
+    /// matching
+    ///
+    /// The algorithm computes a perfect fractional matching. If it
+    /// does not exists, then the algorithm returns false and the
+    /// matching is undefined and the barrier.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    bool startPerfect(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+          _empty_level = _level->maxLevel() - 1;
+          return false;
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+          _empty_level = level;
+          return false;
+        }
+      no_more_push:
+        ;
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+      return true;
+    }
+
+    /// \brief Runs the algorithm
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// start();
+    ///\endcode
+    void run(bool postprocess = true) {
+      init();
+      start(postprocess);
+    }
+
+    /// \brief Runs the algorithm to find a perfect fractional matching
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// startPerfect();
+    ///\endcode
+    bool runPerfect(bool postprocess = true) {
+      init();
+      return startPerfect(postprocess);
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The result of the %Matching algorithm can be obtained using these
+    /// functions.\n
+    /// Before the use of these functions,
+    /// either run() or start() must be called.
+    ///@{
+
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Returns a const reference to the matching map.
+    ///
+    /// Returns a const reference to the node map storing the found
+    /// fractional matching. This method can be called after
+    /// running the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
+        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Returns true if the node is in the barrier
+    ///
+    /// The barrier is a subset of the nodes. If the nodes in the
+    /// barrier have less adjacent nodes than the size of the barrier,
+    /// then at least as much nodes cannot be covered as the
+    /// difference of the two subsets.
+    bool barrier(const Node& node) const {
+      return (*_level)[node] >= _empty_level;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional matching is a relaxation of the
+  /// maximum weighted matching problem where the odd set constraints
+  /// are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// proof of the optimality. The solution of the dual problem can be
+  /// used to check the result of the algorithm. The dual linear
+  /// problem is the following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[y_u \ge 0 \quad \forall u \in V\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution. It is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta1_index;
+    BinHeap<Value, IntNodeMap> *_delta1;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta1) {
+        _delta1_index = new IntNodeMap(_graph);
+        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta1) {
+        delete _delta1_index;
+        delete _delta1;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      _delta1->push(node, (*_node_potential)[node]);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _delta1->erase(node);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+
+    void unmatchNode(const Node& node) {
+      int tree = _tree_set->find(node);
+
+      alternatePath(node, tree);
+      destroyTree(tree);
+
+      _matching->set(node, INVALID);
+    }
+
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
+                                  bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta1_index(0), _delta1(0),
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = 0;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+        _delta1->push(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    void start() {
+      enum OpType {
+        D1, D2, D3
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d1 = !_delta1->empty() ?
+          _delta1->prio() : std::numeric_limits<Value>::max();
+
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        switch (ot) {
+        case D1:
+          {
+            Node n = _delta1->top();
+            unmatchNode(n);
+            --unmatched;
+          }
+          break;
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwfm.init();
+    ///   mwfm.start();
+    /// \endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional perfect matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional perfect matching is a relaxation
+  /// of the maximum weighted perfect matching problem where the odd
+  /// set constraints are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// proof of the optimality. The solution of the dual problem can be
+  /// used to check the result of the algorithm. The dual linear
+  /// problem is the following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedPerfectFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution. It is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedPerfectFractionalMatching(const Graph& graph,
+                                         const WeightMap& weight,
+                                         bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedPerfectFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = - std::numeric_limits<Value>::max();
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    bool start() {
+      enum OpType {
+        D2, D3
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        if (_delta_sum == std::numeric_limits<Value>::max()) {
+          return false;
+        }
+
+        switch (ot) {
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+      return true;
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
+    /// algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwpfm.init();
+    ///   mwpfm.start();
+    /// \endcode
+    bool run() {
+      init();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_FRACTIONAL_MATCHING_H
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 834)
+++ lemon/full_graph.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -204,5 +204,5 @@
     /// \brief Returns the node with the given index.
     ///
-    /// Returns the node with the given index. Since this structure is 
+    /// Returns the node with the given index. Since this structure is
     /// completely static, the nodes can be indexed with integers from
     /// the range <tt>[0..nodeNum()-1]</tt>.
@@ -213,5 +213,5 @@
     /// \brief Returns the index of the given node.
     ///
-    /// Returns the index of the given node. Since this structure is 
+    /// Returns the index of the given node. Since this structure is
     /// completely static, the nodes can be indexed with integers from
     /// the range <tt>[0..nodeNum()-1]</tt>.
@@ -583,5 +583,5 @@
     /// \brief Returns the node with the given index.
     ///
-    /// Returns the node with the given index. Since this structure is 
+    /// Returns the node with the given index. Since this structure is
     /// completely static, the nodes can be indexed with integers from
     /// the range <tt>[0..nodeNum()-1]</tt>.
@@ -592,5 +592,5 @@
     /// \brief Returns the index of the given node.
     ///
-    /// Returns the index of the given node. Since this structure is 
+    /// Returns the index of the given node. Since this structure is
     /// completely static, the nodes can be indexed with integers from
     /// the range <tt>[0..nodeNum()-1]</tt>.
Index: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 793)
+++ lemon/glpk.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -60,5 +60,5 @@
   }
 
-  int GlpkBase::_addRow(Value lo, ExprIterator b, 
+  int GlpkBase::_addRow(Value lo, ExprIterator b,
                         ExprIterator e, Value up) {
     int i = glp_add_rows(lp, 1);
@@ -69,9 +69,9 @@
       } else {
         glp_set_row_bnds(lp, i, GLP_UP, lo, up);
-      }    
+      }
     } else {
       if (up == INF) {
         glp_set_row_bnds(lp, i, GLP_LO, lo, up);
-      } else if (lo != up) {        
+      } else if (lo != up) {
         glp_set_row_bnds(lp, i, GLP_DB, lo, up);
       } else {
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 902)
+++ lemon/glpk.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -31,5 +31,5 @@
     class VoidPtr {
     private:
-      void *_ptr;      
+      void *_ptr;
     public:
       VoidPtr() : _ptr(0) {}
@@ -39,6 +39,6 @@
 
       template <typename T>
-      VoidPtr& operator=(T* ptr) { 
-        _ptr = reinterpret_cast<void*>(ptr); 
+      VoidPtr& operator=(T* ptr) {
+        _ptr = reinterpret_cast<void*>(ptr);
         return *this;
       }
@@ -125,11 +125,11 @@
       }
     };
-    
+
     static FreeEnvHelper freeEnvHelper;
 
   protected:
-    
+
     int _message_level;
-    
+
   public:
 
Index: lemon/gomory_hu.h
===================================================================
--- lemon/gomory_hu.h	(revision 833)
+++ lemon/gomory_hu.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -28,5 +28,5 @@
 
 /// \ingroup min_cut
-/// \file 
+/// \file
 /// \brief Gomory-Hu cut tree in graphs.
 
@@ -39,5 +39,5 @@
   /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
   /// may contain edges which are not in the original graph. It has the
-  /// property that the minimum capacity edge of the path between two nodes 
+  /// property that the minimum capacity edge of the path between two nodes
   /// in this tree has the same weight as the minimum cut in the graph
   /// between these nodes. Moreover the components obtained by removing
@@ -45,5 +45,5 @@
   /// Therefore once this tree is computed, the minimum cut between any pair
   /// of nodes can easily be obtained.
-  /// 
+  ///
   /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
   /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
@@ -61,8 +61,8 @@
 #ifdef DOXYGEN
   template <typename GR,
-	    typename CAP>
+            typename CAP>
 #else
   template <typename GR,
-	    typename CAP = typename GR::template EdgeMap<int> >
+            typename CAP = typename GR::template EdgeMap<int> >
 #endif
   class GomoryHu {
@@ -75,5 +75,5 @@
     /// The value type of capacities
     typedef typename Capacity::Value Value;
-    
+
   private:
 
@@ -90,11 +90,11 @@
     void createStructures() {
       if (!_pred) {
-	_pred = new typename Graph::template NodeMap<Node>(_graph);
+        _pred = new typename Graph::template NodeMap<Node>(_graph);
       }
       if (!_weight) {
-	_weight = new typename Graph::template NodeMap<Value>(_graph);
+        _weight = new typename Graph::template NodeMap<Value>(_graph);
       }
       if (!_order) {
-	_order = new typename Graph::template NodeMap<int>(_graph);
+        _order = new typename Graph::template NodeMap<int>(_graph);
       }
     }
@@ -102,14 +102,14 @@
     void destroyStructures() {
       if (_pred) {
-	delete _pred;
+        delete _pred;
       }
       if (_weight) {
-	delete _weight;
+        delete _weight;
       }
       if (_order) {
-	delete _order;
-      }
-    }
-  
+        delete _order;
+      }
+    }
+
   public:
 
@@ -119,7 +119,7 @@
     /// \param graph The undirected graph the algorithm runs on.
     /// \param capacity The edge capacity map.
-    GomoryHu(const Graph& graph, const Capacity& capacity) 
+    GomoryHu(const Graph& graph, const Capacity& capacity)
       : _graph(graph), _capacity(capacity),
-	_pred(0), _weight(0), _order(0) 
+        _pred(0), _weight(0), _order(0)
     {
       checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
@@ -135,5 +135,5 @@
 
   private:
-  
+
     // Initialize the internal data structures
     void init() {
@@ -146,5 +146,5 @@
       }
       (*_pred)[_root] = INVALID;
-      (*_weight)[_root] = std::numeric_limits<Value>::max(); 
+      (*_weight)[_root] = std::numeric_limits<Value>::max();
     }
 
@@ -155,25 +155,25 @@
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	if (n == _root) continue;
-
-	Node pn = (*_pred)[n];
-	fa.source(n);
-	fa.target(pn);
-
-	fa.runMinCut();
-
-	(*_weight)[n] = fa.flowValue();
-
-	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
-	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
-	    (*_pred)[nn] = n;
-	  }
-	}
-	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
-	  (*_pred)[n] = (*_pred)[pn];
-	  (*_pred)[pn] = n;
-	  (*_weight)[n] = (*_weight)[pn];
-	  (*_weight)[pn] = fa.flowValue();
-	}
+        if (n == _root) continue;
+
+        Node pn = (*_pred)[n];
+        fa.source(n);
+        fa.target(pn);
+
+        fa.runMinCut();
+
+        (*_weight)[n] = fa.flowValue();
+
+        for (NodeIt nn(_graph); nn != INVALID; ++nn) {
+          if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
+            (*_pred)[nn] = n;
+          }
+        }
+        if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
+          (*_pred)[n] = (*_pred)[pn];
+          (*_pred)[pn] = n;
+          (*_weight)[n] = (*_weight)[pn];
+          (*_weight)[pn] = fa.flowValue();
+        }
       }
 
@@ -182,14 +182,14 @@
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	std::vector<Node> st;
-	Node nn = n;
-	while ((*_order)[nn] == -1) {
-	  st.push_back(nn);
-	  nn = (*_pred)[nn];
-	}
-	while (!st.empty()) {
-	  (*_order)[st.back()] = index++;
-	  st.pop_back();
-	}
+        std::vector<Node> st;
+        Node nn = n;
+        while ((*_order)[nn] == -1) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          (*_order)[st.back()] = index++;
+          st.pop_back();
+        }
       }
     }
@@ -198,5 +198,5 @@
 
     ///\name Execution Control
- 
+
     ///@{
 
@@ -208,5 +208,5 @@
       start();
     }
-    
+
     /// @}
 
@@ -233,5 +233,5 @@
     /// Gomory-Hu tree.
     ///
-    /// This function returns the weight of the predecessor edge of the 
+    /// This function returns the weight of the predecessor edge of the
     /// given node in the Gomory-Hu tree.
     /// If \c node is the root of the tree, the result is undefined.
@@ -255,5 +255,5 @@
     ///
     /// This function returns the minimum cut value between the nodes
-    /// \c s and \c t. 
+    /// \c s and \c t.
     /// It finds the nearest common ancestor of the given nodes in the
     /// Gomory-Hu tree and calculates the minimum weight edge on the
@@ -264,13 +264,13 @@
       Node sn = s, tn = t;
       Value value = std::numeric_limits<Value>::max();
-      
+
       while (sn != tn) {
-	if ((*_order)[sn] < (*_order)[tn]) {
-	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
-	  tn = (*_pred)[tn];
-	} else {
-	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
-	  sn = (*_pred)[sn];
-	}
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) value = (*_weight)[tn];
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) value = (*_weight)[sn];
+          sn = (*_pred)[sn];
+        }
       }
       return value;
@@ -303,21 +303,21 @@
       Node rn = INVALID;
       Value value = std::numeric_limits<Value>::max();
-      
+
       while (sn != tn) {
-	if ((*_order)[sn] < (*_order)[tn]) {
-	  if ((*_weight)[tn] <= value) {
-	    rn = tn;
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) {
+            rn = tn;
             s_root = false;
-	    value = (*_weight)[tn];
-	  }
-	  tn = (*_pred)[tn];
-	} else {
-	  if ((*_weight)[sn] <= value) {
-	    rn = sn;
+            value = (*_weight)[tn];
+          }
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) {
+            rn = sn;
             s_root = true;
-	    value = (*_weight)[sn];
-	  }
-	  sn = (*_pred)[sn];
-	}
+            value = (*_weight)[sn];
+          }
+          sn = (*_pred)[sn];
+        }
       }
 
@@ -330,16 +330,16 @@
       std::vector<Node> st;
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	st.clear();
+        st.clear();
         Node nn = n;
-	while (!reached[nn]) {
-	  st.push_back(nn);
-	  nn = (*_pred)[nn];
-	}
-	while (!st.empty()) {
-	  cutMap.set(st.back(), cutMap[nn]);
-	  st.pop_back();
-	}
-      }
-      
+        while (!reached[nn]) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          cutMap.set(st.back(), cutMap[nn]);
+          st.pop_back();
+        }
+      }
+
       return value;
     }
@@ -350,5 +350,5 @@
 
     /// Iterate on the nodes of a minimum cut
-    
+
     /// This iterator class lists the nodes of a minimum cut found by
     /// GomoryHu. Before using it, you must allocate a GomoryHu class
@@ -443,9 +443,9 @@
       }
     };
-    
+
     friend class MinCutEdgeIt;
-    
+
     /// Iterate on the edges of a minimum cut
-    
+
     /// This iterator class lists the edges of a minimum cut found by
     /// GomoryHu. Before using it, you must allocate a GomoryHu class
@@ -480,5 +480,5 @@
           }
       }
-      
+
     public:
       /// Constructor
@@ -549,5 +549,5 @@
       }
       /// Postfix incrementation
-      
+
       /// Postfix incrementation.
       ///
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 833)
+++ lemon/graph_to_eps.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -685,7 +685,7 @@
 #else
       os << bits::getWinFormattedDate();
+      os << std::endl;
 #endif
     }
-    os << std::endl;
 
     if (_autoArcWidthScale) {
Index: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 644)
+++ lemon/hao_orlin.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,5 +32,5 @@
 /// \brief Implementation of the Hao-Orlin algorithm.
 ///
-/// Implementation of the Hao-Orlin algorithm for finding a minimum cut 
+/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
 /// in a digraph.
 
@@ -42,5 +42,5 @@
   ///
   /// This class implements the Hao-Orlin algorithm for finding a minimum
-  /// value cut in a directed graph \f$D=(V,A)\f$. 
+  /// value cut in a directed graph \f$D=(V,A)\f$.
   /// It takes a fixed node \f$ source \in V \f$ and
   /// consists of two phases: in the first phase it determines a
@@ -59,5 +59,5 @@
   /// For an undirected graph you can run just the first phase of the
   /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
-  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 
+  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
   /// time. It is implemented in the NagamochiIbaraki algorithm class.
   ///
@@ -77,5 +77,5 @@
   class HaoOrlin {
   public:
-   
+
     /// The digraph type of the algorithm
     typedef GR Digraph;
@@ -164,4 +164,21 @@
         delete _flow;
       }
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    HaoOrlin& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
     }
 
@@ -848,5 +865,5 @@
     ///
     /// This function initializes the internal data structures. It creates
-    /// the maps and some bucket structures for the algorithm. 
+    /// the maps and some bucket structures for the algorithm.
     /// The given node is used as the source node for the push-relabel
     /// algorithm.
@@ -928,5 +945,5 @@
     /// \brief Run the algorithm.
     ///
-    /// This function runs the algorithm. It uses the given \c source node, 
+    /// This function runs the algorithm. It uses the given \c source node,
     /// finds a proper \c target node and then calls the \ref init(),
     /// \ref calculateOut() and \ref calculateIn().
@@ -942,5 +959,5 @@
     /// The result of the %HaoOrlin algorithm
     /// can be obtained using these functions.\n
-    /// \ref run(), \ref calculateOut() or \ref calculateIn() 
+    /// \ref run(), \ref calculateOut() or \ref calculateIn()
     /// should be called before using them.
 
@@ -951,5 +968,5 @@
     /// This function returns the value of the minimum cut.
     ///
-    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
     /// must be called before using this function.
     Value minCutValue() const {
@@ -970,5 +987,5 @@
     /// \return The value of the minimum cut.
     ///
-    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
     /// must be called before using this function.
     template <typename CutMap>
Index: mon/hartmann_orlin.h
===================================================================
--- lemon/hartmann_orlin.h	(revision 891)
+++ 	(revision )
@@ -1,646 +1,0 @@
-/* -*- C++ -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library
- *
- * Copyright (C) 2003-2008
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_HARTMANN_ORLIN_H
-#define LEMON_HARTMANN_ORLIN_H
-
-/// \ingroup min_mean_cycle
-///
-/// \file
-/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
-
-#include <vector>
-#include <limits>
-#include <lemon/core.h>
-#include <lemon/path.h>
-#include <lemon/tolerance.h>
-#include <lemon/connectivity.h>
-
-namespace lemon {
-
-  /// \brief Default traits class of HartmannOrlin algorithm.
-  ///
-  /// Default traits class of HartmannOrlin algorithm.
-  /// \tparam GR The type of the digraph.
-  /// \tparam LEN The type of the length map.
-  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN>
-#else
-  template <typename GR, typename LEN,
-    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
-#endif
-  struct HartmannOrlinDefaultTraits
-  {
-    /// The type of the digraph
-    typedef GR Digraph;
-    /// The type of the length map
-    typedef LEN LengthMap;
-    /// The type of the arc lengths
-    typedef typename LengthMap::Value Value;
-
-    /// \brief The large value type used for internal computations
-    ///
-    /// The large value type used for internal computations.
-    /// It is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    /// \c Value must be convertible to \c LargeValue.
-    typedef double LargeValue;
-
-    /// The tolerance type used for internal computations
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addFront() function.
-    typedef lemon::Path<Digraph> Path;
-  };
-
-  // Default traits class for integer value types
-  template <typename GR, typename LEN>
-  struct HartmannOrlinDefaultTraits<GR, LEN, true>
-  {
-    typedef GR Digraph;
-    typedef LEN LengthMap;
-    typedef typename LengthMap::Value Value;
-#ifdef LEMON_HAVE_LONG_LONG
-    typedef long long LargeValue;
-#else
-    typedef long LargeValue;
-#endif
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-    typedef lemon::Path<Digraph> Path;
-  };
-
-
-  /// \addtogroup min_mean_cycle
-  /// @{
-
-  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
-  /// a minimum mean cycle.
-  ///
-  /// This class implements the Hartmann-Orlin algorithm for finding
-  /// a directed cycle of minimum mean length (cost) in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
-  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
-  /// it applies an efficient early termination scheme.
-  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
-  ///
-  /// \tparam GR The type of the digraph the algorithm runs on.
-  /// \tparam LEN The type of the length map. The default
-  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
-  /// \tparam TR The traits class that defines various types used by the
-  /// algorithm. By default, it is \ref HartmannOrlinDefaultTraits
-  /// "HartmannOrlinDefaultTraits<GR, LEN>".
-  /// In most cases, this parameter should not be set directly,
-  /// consider to use the named template parameters instead.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN, typename TR>
-#else
-  template < typename GR,
-             typename LEN = typename GR::template ArcMap<int>,
-             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
-#endif
-  class HartmannOrlin
-  {
-  public:
-
-    /// The type of the digraph
-    typedef typename TR::Digraph Digraph;
-    /// The type of the length map
-    typedef typename TR::LengthMap LengthMap;
-    /// The type of the arc lengths
-    typedef typename TR::Value Value;
-
-    /// \brief The large value type
-    ///
-    /// The large value type used for internal computations.
-    /// By default, it is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    typedef typename TR::LargeValue LargeValue;
-
-    /// The tolerance type
-    typedef typename TR::Tolerance Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
-    /// it is \ref lemon::Path "Path<Digraph>".
-    typedef typename TR::Path Path;
-
-    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
-    typedef TR Traits;
-
-  private:
-
-    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
-
-    // Data sturcture for path data
-    struct PathData
-    {
-      LargeValue dist;
-      Arc pred;
-      PathData(LargeValue d, Arc p = INVALID) :
-        dist(d), pred(p) {}
-    };
-
-    typedef typename Digraph::template NodeMap<std::vector<PathData> >
-      PathDataNodeMap;
-
-  private:
-
-    // The digraph the algorithm runs on
-    const Digraph &_gr;
-    // The length of the arcs
-    const LengthMap &_length;
-
-    // Data for storing the strongly connected components
-    int _comp_num;
-    typename Digraph::template NodeMap<int> _comp;
-    std::vector<std::vector<Node> > _comp_nodes;
-    std::vector<Node>* _nodes;
-    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
-
-    // Data for the found cycles
-    bool _curr_found, _best_found;
-    LargeValue _curr_length, _best_length;
-    int _curr_size, _best_size;
-    Node _curr_node, _best_node;
-    int _curr_level, _best_level;
-
-    Path *_cycle_path;
-    bool _local_path;
-
-    // Node map for storing path data
-    PathDataNodeMap _data;
-    // The processed nodes in the last round
-    std::vector<Node> _process;
-
-    Tolerance _tolerance;
-
-    // Infinite constant
-    const LargeValue INF;
-
-  public:
-
-    /// \name Named Template Parameters
-    /// @{
-
-    template <typename T>
-    struct SetLargeValueTraits : public Traits {
-      typedef T LargeValue;
-      typedef lemon::Tolerance<T> Tolerance;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c LargeValue type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
-    /// type. It is used for internal computations in the algorithm.
-    template <typename T>
-    struct SetLargeValue
-      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
-      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
-    };
-
-    template <typename T>
-    struct SetPathTraits : public Traits {
-      typedef T Path;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c %Path type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting the \c %Path
-    /// type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addFront() function.
-    template <typename T>
-    struct SetPath
-      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
-      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
-    };
-
-    /// @}
-
-  public:
-
-    /// \brief Constructor.
-    ///
-    /// The constructor of the class.
-    ///
-    /// \param digraph The digraph the algorithm runs on.
-    /// \param length The lengths (costs) of the arcs.
-    HartmannOrlin( const Digraph &digraph,
-                   const LengthMap &length ) :
-      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
-      _best_found(false), _best_length(0), _best_size(1),
-      _cycle_path(NULL), _local_path(false), _data(digraph),
-      INF(std::numeric_limits<LargeValue>::has_infinity ?
-          std::numeric_limits<LargeValue>::infinity() :
-          std::numeric_limits<LargeValue>::max())
-    {}
-
-    /// Destructor.
-    ~HartmannOrlin() {
-      if (_local_path) delete _cycle_path;
-    }
-
-    /// \brief Set the path structure for storing the found cycle.
-    ///
-    /// This function sets an external path structure for storing the
-    /// found cycle.
-    ///
-    /// If you don't call this function before calling \ref run() or
-    /// \ref findMinMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
-    /// allocated object, of course.
-    ///
-    /// \note The algorithm calls only the \ref lemon::Path::addFront()
-    /// "addFront()" function of the given path structure.
-    ///
-    /// \return <tt>(*this)</tt>
-    HartmannOrlin& cycle(Path &path) {
-      if (_local_path) {
-        delete _cycle_path;
-        _local_path = false;
-      }
-      _cycle_path = &path;
-      return *this;
-    }
-
-    /// \brief Set the tolerance used by the algorithm.
-    ///
-    /// This function sets the tolerance object used by the algorithm.
-    ///
-    /// \return <tt>(*this)</tt>
-    HartmannOrlin& tolerance(const Tolerance& tolerance) {
-      _tolerance = tolerance;
-      return *this;
-    }
-
-    /// \brief Return a const reference to the tolerance.
-    ///
-    /// This function returns a const reference to the tolerance object
-    /// used by the algorithm.
-    const Tolerance& tolerance() const {
-      return _tolerance;
-    }
-
-    /// \name Execution control
-    /// The simplest way to execute the algorithm is to call the \ref run()
-    /// function.\n
-    /// If you only need the minimum mean length, you may call
-    /// \ref findMinMean().
-
-    /// @{
-
-    /// \brief Run the algorithm.
-    ///
-    /// This function runs the algorithm.
-    /// It can be called more than once (e.g. if the underlying digraph
-    /// and/or the arc lengths have been modified).
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
-    /// \code
-    ///   return mmc.findMinMean() && mmc.findCycle();
-    /// \endcode
-    bool run() {
-      return findMinMean() && findCycle();
-    }
-
-    /// \brief Find the minimum cycle mean.
-    ///
-    /// This function finds the minimum mean length of the directed
-    /// cycles in the digraph.
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    bool findMinMean() {
-      // Initialization and find strongly connected components
-      init();
-      findComponents();
-      
-      // Find the minimum cycle mean in the components
-      for (int comp = 0; comp < _comp_num; ++comp) {
-        if (!initComponent(comp)) continue;
-        processRounds();
-        
-        // Update the best cycle (global minimum mean cycle)
-        if ( _curr_found && (!_best_found || 
-             _curr_length * _best_size < _best_length * _curr_size) ) {
-          _best_found = true;
-          _best_length = _curr_length;
-          _best_size = _curr_size;
-          _best_node = _curr_node;
-          _best_level = _curr_level;
-        }
-      }
-      return _best_found;
-    }
-
-    /// \brief Find a minimum mean directed cycle.
-    ///
-    /// This function finds a directed cycle of minimum mean length
-    /// in the digraph using the data computed by findMinMean().
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \pre \ref findMinMean() must be called before using this function.
-    bool findCycle() {
-      if (!_best_found) return false;
-      IntNodeMap reached(_gr, -1);
-      int r = _best_level + 1;
-      Node u = _best_node;
-      while (reached[u] < 0) {
-        reached[u] = --r;
-        u = _gr.source(_data[u][r].pred);
-      }
-      r = reached[u];
-      Arc e = _data[u][r].pred;
-      _cycle_path->addFront(e);
-      _best_length = _length[e];
-      _best_size = 1;
-      Node v;
-      while ((v = _gr.source(e)) != u) {
-        e = _data[v][--r].pred;
-        _cycle_path->addFront(e);
-        _best_length += _length[e];
-        ++_best_size;
-      }
-      return true;
-    }
-
-    /// @}
-
-    /// \name Query Functions
-    /// The results of the algorithm can be obtained using these
-    /// functions.\n
-    /// The algorithm should be executed before using them.
-
-    /// @{
-
-    /// \brief Return the total length of the found cycle.
-    ///
-    /// This function returns the total length of the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    LargeValue cycleLength() const {
-      return _best_length;
-    }
-
-    /// \brief Return the number of arcs on the found cycle.
-    ///
-    /// This function returns the number of arcs on the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    int cycleArcNum() const {
-      return _best_size;
-    }
-
-    /// \brief Return the mean length of the found cycle.
-    ///
-    /// This function returns the mean length of the found cycle.
-    ///
-    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
-    /// following code.
-    /// \code
-    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
-    /// \endcode
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    double cycleMean() const {
-      return static_cast<double>(_best_length) / _best_size;
-    }
-
-    /// \brief Return the found cycle.
-    ///
-    /// This function returns a const reference to the path structure
-    /// storing the found cycle.
-    ///
-    /// \pre \ref run() or \ref findCycle() must be called before using
-    /// this function.
-    const Path& cycle() const {
-      return *_cycle_path;
-    }
-
-    ///@}
-
-  private:
-
-    // Initialization
-    void init() {
-      if (!_cycle_path) {
-        _local_path = true;
-        _cycle_path = new Path;
-      }
-      _cycle_path->clear();
-      _best_found = false;
-      _best_length = 0;
-      _best_size = 1;
-      _cycle_path->clear();
-      for (NodeIt u(_gr); u != INVALID; ++u)
-        _data[u].clear();
-    }
-
-    // Find strongly connected components and initialize _comp_nodes
-    // and _out_arcs
-    void findComponents() {
-      _comp_num = stronglyConnectedComponents(_gr, _comp);
-      _comp_nodes.resize(_comp_num);
-      if (_comp_num == 1) {
-        _comp_nodes[0].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          _comp_nodes[0].push_back(n);
-          _out_arcs[n].clear();
-          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
-            _out_arcs[n].push_back(a);
-          }
-        }
-      } else {
-        for (int i = 0; i < _comp_num; ++i)
-          _comp_nodes[i].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          int k = _comp[n];
-          _comp_nodes[k].push_back(n);
-          _out_arcs[n].clear();
-          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
-            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
-          }
-        }
-      }
-    }
-
-    // Initialize path data for the current component
-    bool initComponent(int comp) {
-      _nodes = &(_comp_nodes[comp]);
-      int n = _nodes->size();
-      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
-        return false;
-      }      
-      for (int i = 0; i < n; ++i) {
-        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
-      }
-      return true;
-    }
-
-    // Process all rounds of computing path data for the current component.
-    // _data[v][k] is the length of a shortest directed walk from the root
-    // node to node v containing exactly k arcs.
-    void processRounds() {
-      Node start = (*_nodes)[0];
-      _data[start][0] = PathData(0);
-      _process.clear();
-      _process.push_back(start);
-
-      int k, n = _nodes->size();
-      int next_check = 4;
-      bool terminate = false;
-      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
-        processNextBuildRound(k);
-        if (k == next_check || k == n) {
-          terminate = checkTermination(k);
-          next_check = next_check * 3 / 2;
-        }
-      }
-      for ( ; k <= n && !terminate; ++k) {
-        processNextFullRound(k);
-        if (k == next_check || k == n) {
-          terminate = checkTermination(k);
-          next_check = next_check * 3 / 2;
-        }
-      }
-    }
-
-    // Process one round and rebuild _process
-    void processNextBuildRound(int k) {
-      std::vector<Node> next;
-      Node u, v;
-      Arc e;
-      LargeValue d;
-      for (int i = 0; i < int(_process.size()); ++i) {
-        u = _process[i];
-        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
-          e = _out_arcs[u][j];
-          v = _gr.target(e);
-          d = _data[u][k-1].dist + _length[e];
-          if (_tolerance.less(d, _data[v][k].dist)) {
-            if (_data[v][k].dist == INF) next.push_back(v);
-            _data[v][k] = PathData(d, e);
-          }
-        }
-      }
-      _process.swap(next);
-    }
-
-    // Process one round using _nodes instead of _process
-    void processNextFullRound(int k) {
-      Node u, v;
-      Arc e;
-      LargeValue d;
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        u = (*_nodes)[i];
-        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
-          e = _out_arcs[u][j];
-          v = _gr.target(e);
-          d = _data[u][k-1].dist + _length[e];
-          if (_tolerance.less(d, _data[v][k].dist)) {
-            _data[v][k] = PathData(d, e);
-          }
-        }
-      }
-    }
-    
-    // Check early termination
-    bool checkTermination(int k) {
-      typedef std::pair<int, int> Pair;
-      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
-      typename GR::template NodeMap<LargeValue> pi(_gr);
-      int n = _nodes->size();
-      LargeValue length;
-      int size;
-      Node u;
-      
-      // Search for cycles that are already found
-      _curr_found = false;
-      for (int i = 0; i < n; ++i) {
-        u = (*_nodes)[i];
-        if (_data[u][k].dist == INF) continue;
-        for (int j = k; j >= 0; --j) {
-          if (level[u].first == i && level[u].second > 0) {
-            // A cycle is found
-            length = _data[u][level[u].second].dist - _data[u][j].dist;
-            size = level[u].second - j;
-            if (!_curr_found || length * _curr_size < _curr_length * size) {
-              _curr_length = length;
-              _curr_size = size;
-              _curr_node = u;
-              _curr_level = level[u].second;
-              _curr_found = true;
-            }
-          }
-          level[u] = Pair(i, j);
-          if (j != 0) {
-	    u = _gr.source(_data[u][j].pred);
-	  }
-        }
-      }
-
-      // If at least one cycle is found, check the optimality condition
-      LargeValue d;
-      if (_curr_found && k < n) {
-        // Find node potentials
-        for (int i = 0; i < n; ++i) {
-          u = (*_nodes)[i];
-          pi[u] = INF;
-          for (int j = 0; j <= k; ++j) {
-            if (_data[u][j].dist < INF) {
-              d = _data[u][j].dist * _curr_size - j * _curr_length;
-              if (_tolerance.less(d, pi[u])) pi[u] = d;
-            }
-          }
-        }
-
-        // Check the optimality condition for all arcs
-        bool done = true;
-        for (ArcIt a(_gr); a != INVALID; ++a) {
-          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
-                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
-            done = false;
-            break;
-          }
-        }
-        return done;
-      }
-      return (k == n);
-    }
-
-  }; //class HartmannOrlin
-
-  ///@}
-
-} //namespace lemon
-
-#endif //LEMON_HARTMANN_ORLIN_H
Index: lemon/hartmann_orlin_mmc.h
===================================================================
--- lemon/hartmann_orlin_mmc.h	(revision 959)
+++ lemon/hartmann_orlin_mmc.h	(revision 959)
@@ -0,0 +1,650 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HARTMANN_ORLIN_MMC_H
+#define LEMON_HARTMANN_ORLIN_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HartmannOrlinMmc class.
+  ///
+  /// Default traits class of HartmannOrlinMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HartmannOrlinMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
+  /// a minimum mean cycle.
+  ///
+  /// This class implements the Hartmann-Orlin algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
+  /// it applies an efficient early termination scheme.
+  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
+  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
+#endif
+  class HartmannOrlinMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+    int _curr_level, _best_level;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HartmannOrlinMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HartmannOrlinMmc( const Digraph &digraph,
+                      const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _best_found(false), _best_cost(0), _best_size(1),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HartmannOrlinMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+          _best_level = _curr_level;
+        }
+      }
+      return _best_found;
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _best_level + 1;
+      Node u = _best_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _best_cost = _cost[e];
+      _best_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _best_cost += _cost[e];
+        ++_best_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      int next_check = 4;
+      bool terminate = false;
+      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
+        processNextBuildRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+      for ( ; k <= n && !terminate; ++k) {
+        processNextFullRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Check early termination
+    bool checkTermination(int k) {
+      typedef std::pair<int, int> Pair;
+      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
+      typename GR::template NodeMap<LargeCost> pi(_gr);
+      int n = _nodes->size();
+      LargeCost cost;
+      int size;
+      Node u;
+
+      // Search for cycles that are already found
+      _curr_found = false;
+      for (int i = 0; i < n; ++i) {
+        u = (*_nodes)[i];
+        if (_data[u][k].dist == INF) continue;
+        for (int j = k; j >= 0; --j) {
+          if (level[u].first == i && level[u].second > 0) {
+            // A cycle is found
+            cost = _data[u][level[u].second].dist - _data[u][j].dist;
+            size = level[u].second - j;
+            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
+              _curr_cost = cost;
+              _curr_size = size;
+              _curr_node = u;
+              _curr_level = level[u].second;
+              _curr_found = true;
+            }
+          }
+          level[u] = Pair(i, j);
+          if (j != 0) {
+            u = _gr.source(_data[u][j].pred);
+          }
+        }
+      }
+
+      // If at least one cycle is found, check the optimality condition
+      LargeCost d;
+      if (_curr_found && k < n) {
+        // Find node potentials
+        for (int i = 0; i < n; ++i) {
+          u = (*_nodes)[i];
+          pi[u] = INF;
+          for (int j = 0; j <= k; ++j) {
+            if (_data[u][j].dist < INF) {
+              d = _data[u][j].dist * _curr_size - j * _curr_cost;
+              if (_tolerance.less(d, pi[u])) pi[u] = d;
+            }
+          }
+        }
+
+        // Check the optimality condition for all arcs
+        bool done = true;
+        for (ArcIt a(_gr); a != INVALID; ++a) {
+          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
+                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
+            done = false;
+            break;
+          }
+        }
+        return done;
+      }
+      return (k == n);
+    }
+
+  }; //class HartmannOrlinMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HARTMANN_ORLIN_MMC_H
Index: mon/howard.h
===================================================================
--- lemon/howard.h	(revision 891)
+++ 	(revision )
@@ -1,601 +1,0 @@
-/* -*- C++ -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library
- *
- * Copyright (C) 2003-2008
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_HOWARD_H
-#define LEMON_HOWARD_H
-
-/// \ingroup min_mean_cycle
-///
-/// \file
-/// \brief Howard's algorithm for finding a minimum mean cycle.
-
-#include <vector>
-#include <limits>
-#include <lemon/core.h>
-#include <lemon/path.h>
-#include <lemon/tolerance.h>
-#include <lemon/connectivity.h>
-
-namespace lemon {
-
-  /// \brief Default traits class of Howard class.
-  ///
-  /// Default traits class of Howard class.
-  /// \tparam GR The type of the digraph.
-  /// \tparam LEN The type of the length map.
-  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN>
-#else
-  template <typename GR, typename LEN,
-    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
-#endif
-  struct HowardDefaultTraits
-  {
-    /// The type of the digraph
-    typedef GR Digraph;
-    /// The type of the length map
-    typedef LEN LengthMap;
-    /// The type of the arc lengths
-    typedef typename LengthMap::Value Value;
-
-    /// \brief The large value type used for internal computations
-    ///
-    /// The large value type used for internal computations.
-    /// It is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    /// \c Value must be convertible to \c LargeValue.
-    typedef double LargeValue;
-
-    /// The tolerance type used for internal computations
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addBack() function.
-    typedef lemon::Path<Digraph> Path;
-  };
-
-  // Default traits class for integer value types
-  template <typename GR, typename LEN>
-  struct HowardDefaultTraits<GR, LEN, true>
-  {
-    typedef GR Digraph;
-    typedef LEN LengthMap;
-    typedef typename LengthMap::Value Value;
-#ifdef LEMON_HAVE_LONG_LONG
-    typedef long long LargeValue;
-#else
-    typedef long LargeValue;
-#endif
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-    typedef lemon::Path<Digraph> Path;
-  };
-
-
-  /// \addtogroup min_mean_cycle
-  /// @{
-
-  /// \brief Implementation of Howard's algorithm for finding a minimum
-  /// mean cycle.
-  ///
-  /// This class implements Howard's policy iteration algorithm for finding
-  /// a directed cycle of minimum mean length (cost) in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
-  /// This class provides the most efficient algorithm for the
-  /// minimum mean cycle problem, though the best known theoretical
-  /// bound on its running time is exponential.
-  ///
-  /// \tparam GR The type of the digraph the algorithm runs on.
-  /// \tparam LEN The type of the length map. The default
-  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
-  /// \tparam TR The traits class that defines various types used by the
-  /// algorithm. By default, it is \ref HowardDefaultTraits
-  /// "HowardDefaultTraits<GR, LEN>".
-  /// In most cases, this parameter should not be set directly,
-  /// consider to use the named template parameters instead.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN, typename TR>
-#else
-  template < typename GR,
-             typename LEN = typename GR::template ArcMap<int>,
-             typename TR = HowardDefaultTraits<GR, LEN> >
-#endif
-  class Howard
-  {
-  public:
-  
-    /// The type of the digraph
-    typedef typename TR::Digraph Digraph;
-    /// The type of the length map
-    typedef typename TR::LengthMap LengthMap;
-    /// The type of the arc lengths
-    typedef typename TR::Value Value;
-
-    /// \brief The large value type
-    ///
-    /// The large value type used for internal computations.
-    /// By default, it is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    typedef typename TR::LargeValue LargeValue;
-
-    /// The tolerance type
-    typedef typename TR::Tolerance Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// Using the \ref HowardDefaultTraits "default traits class",
-    /// it is \ref lemon::Path "Path<Digraph>".
-    typedef typename TR::Path Path;
-
-    /// The \ref HowardDefaultTraits "traits class" of the algorithm
-    typedef TR Traits;
-
-  private:
-
-    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
-  
-    // The digraph the algorithm runs on
-    const Digraph &_gr;
-    // The length of the arcs
-    const LengthMap &_length;
-
-    // Data for the found cycles
-    bool _curr_found, _best_found;
-    LargeValue _curr_length, _best_length;
-    int _curr_size, _best_size;
-    Node _curr_node, _best_node;
-
-    Path *_cycle_path;
-    bool _local_path;
-
-    // Internal data used by the algorithm
-    typename Digraph::template NodeMap<Arc> _policy;
-    typename Digraph::template NodeMap<bool> _reached;
-    typename Digraph::template NodeMap<int> _level;
-    typename Digraph::template NodeMap<LargeValue> _dist;
-
-    // Data for storing the strongly connected components
-    int _comp_num;
-    typename Digraph::template NodeMap<int> _comp;
-    std::vector<std::vector<Node> > _comp_nodes;
-    std::vector<Node>* _nodes;
-    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
-    
-    // Queue used for BFS search
-    std::vector<Node> _queue;
-    int _qfront, _qback;
-
-    Tolerance _tolerance;
-  
-    // Infinite constant
-    const LargeValue INF;
-
-  public:
-  
-    /// \name Named Template Parameters
-    /// @{
-
-    template <typename T>
-    struct SetLargeValueTraits : public Traits {
-      typedef T LargeValue;
-      typedef lemon::Tolerance<T> Tolerance;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c LargeValue type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
-    /// type. It is used for internal computations in the algorithm.
-    template <typename T>
-    struct SetLargeValue
-      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
-      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
-    };
-
-    template <typename T>
-    struct SetPathTraits : public Traits {
-      typedef T Path;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c %Path type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting the \c %Path
-    /// type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addBack() function.
-    template <typename T>
-    struct SetPath
-      : public Howard<GR, LEN, SetPathTraits<T> > {
-      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
-    };
-    
-    /// @}
-
-  public:
-
-    /// \brief Constructor.
-    ///
-    /// The constructor of the class.
-    ///
-    /// \param digraph The digraph the algorithm runs on.
-    /// \param length The lengths (costs) of the arcs.
-    Howard( const Digraph &digraph,
-            const LengthMap &length ) :
-      _gr(digraph), _length(length), _best_found(false),
-      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
-      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
-      _comp(digraph), _in_arcs(digraph),
-      INF(std::numeric_limits<LargeValue>::has_infinity ?
-          std::numeric_limits<LargeValue>::infinity() :
-          std::numeric_limits<LargeValue>::max())
-    {}
-
-    /// Destructor.
-    ~Howard() {
-      if (_local_path) delete _cycle_path;
-    }
-
-    /// \brief Set the path structure for storing the found cycle.
-    ///
-    /// This function sets an external path structure for storing the
-    /// found cycle.
-    ///
-    /// If you don't call this function before calling \ref run() or
-    /// \ref findMinMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
-    /// allocated object, of course.
-    ///
-    /// \note The algorithm calls only the \ref lemon::Path::addBack()
-    /// "addBack()" function of the given path structure.
-    ///
-    /// \return <tt>(*this)</tt>
-    Howard& cycle(Path &path) {
-      if (_local_path) {
-        delete _cycle_path;
-        _local_path = false;
-      }
-      _cycle_path = &path;
-      return *this;
-    }
-
-    /// \brief Set the tolerance used by the algorithm.
-    ///
-    /// This function sets the tolerance object used by the algorithm.
-    ///
-    /// \return <tt>(*this)</tt>
-    Howard& tolerance(const Tolerance& tolerance) {
-      _tolerance = tolerance;
-      return *this;
-    }
-
-    /// \brief Return a const reference to the tolerance.
-    ///
-    /// This function returns a const reference to the tolerance object
-    /// used by the algorithm.
-    const Tolerance& tolerance() const {
-      return _tolerance;
-    }
-
-    /// \name Execution control
-    /// The simplest way to execute the algorithm is to call the \ref run()
-    /// function.\n
-    /// If you only need the minimum mean length, you may call
-    /// \ref findMinMean().
-
-    /// @{
-
-    /// \brief Run the algorithm.
-    ///
-    /// This function runs the algorithm.
-    /// It can be called more than once (e.g. if the underlying digraph
-    /// and/or the arc lengths have been modified).
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
-    /// \code
-    ///   return mmc.findMinMean() && mmc.findCycle();
-    /// \endcode
-    bool run() {
-      return findMinMean() && findCycle();
-    }
-
-    /// \brief Find the minimum cycle mean.
-    ///
-    /// This function finds the minimum mean length of the directed
-    /// cycles in the digraph.
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    bool findMinMean() {
-      // Initialize and find strongly connected components
-      init();
-      findComponents();
-      
-      // Find the minimum cycle mean in the components
-      for (int comp = 0; comp < _comp_num; ++comp) {
-        // Find the minimum mean cycle in the current component
-        if (!buildPolicyGraph(comp)) continue;
-        while (true) {
-          findPolicyCycle();
-          if (!computeNodeDistances()) break;
-        }
-        // Update the best cycle (global minimum mean cycle)
-        if ( _curr_found && (!_best_found ||
-             _curr_length * _best_size < _best_length * _curr_size) ) {
-          _best_found = true;
-          _best_length = _curr_length;
-          _best_size = _curr_size;
-          _best_node = _curr_node;
-        }
-      }
-      return _best_found;
-    }
-
-    /// \brief Find a minimum mean directed cycle.
-    ///
-    /// This function finds a directed cycle of minimum mean length
-    /// in the digraph using the data computed by findMinMean().
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \pre \ref findMinMean() must be called before using this function.
-    bool findCycle() {
-      if (!_best_found) return false;
-      _cycle_path->addBack(_policy[_best_node]);
-      for ( Node v = _best_node;
-            (v = _gr.target(_policy[v])) != _best_node; ) {
-        _cycle_path->addBack(_policy[v]);
-      }
-      return true;
-    }
-
-    /// @}
-
-    /// \name Query Functions
-    /// The results of the algorithm can be obtained using these
-    /// functions.\n
-    /// The algorithm should be executed before using them.
-
-    /// @{
-
-    /// \brief Return the total length of the found cycle.
-    ///
-    /// This function returns the total length of the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    LargeValue cycleLength() const {
-      return _best_length;
-    }
-
-    /// \brief Return the number of arcs on the found cycle.
-    ///
-    /// This function returns the number of arcs on the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    int cycleArcNum() const {
-      return _best_size;
-    }
-
-    /// \brief Return the mean length of the found cycle.
-    ///
-    /// This function returns the mean length of the found cycle.
-    ///
-    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
-    /// following code.
-    /// \code
-    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
-    /// \endcode
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    double cycleMean() const {
-      return static_cast<double>(_best_length) / _best_size;
-    }
-
-    /// \brief Return the found cycle.
-    ///
-    /// This function returns a const reference to the path structure
-    /// storing the found cycle.
-    ///
-    /// \pre \ref run() or \ref findCycle() must be called before using
-    /// this function.
-    const Path& cycle() const {
-      return *_cycle_path;
-    }
-
-    ///@}
-
-  private:
-
-    // Initialize
-    void init() {
-      if (!_cycle_path) {
-        _local_path = true;
-        _cycle_path = new Path;
-      }
-      _queue.resize(countNodes(_gr));
-      _best_found = false;
-      _best_length = 0;
-      _best_size = 1;
-      _cycle_path->clear();
-    }
-    
-    // Find strongly connected components and initialize _comp_nodes
-    // and _in_arcs
-    void findComponents() {
-      _comp_num = stronglyConnectedComponents(_gr, _comp);
-      _comp_nodes.resize(_comp_num);
-      if (_comp_num == 1) {
-        _comp_nodes[0].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          _comp_nodes[0].push_back(n);
-          _in_arcs[n].clear();
-          for (InArcIt a(_gr, n); a != INVALID; ++a) {
-            _in_arcs[n].push_back(a);
-          }
-        }
-      } else {
-        for (int i = 0; i < _comp_num; ++i)
-          _comp_nodes[i].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          int k = _comp[n];
-          _comp_nodes[k].push_back(n);
-          _in_arcs[n].clear();
-          for (InArcIt a(_gr, n); a != INVALID; ++a) {
-            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
-          }
-        }
-      }
-    }
-
-    // Build the policy graph in the given strongly connected component
-    // (the out-degree of every node is 1)
-    bool buildPolicyGraph(int comp) {
-      _nodes = &(_comp_nodes[comp]);
-      if (_nodes->size() < 1 ||
-          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
-        return false;
-      }
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        _dist[(*_nodes)[i]] = INF;
-      }
-      Node u, v;
-      Arc e;
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        v = (*_nodes)[i];
-        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
-          e = _in_arcs[v][j];
-          u = _gr.source(e);
-          if (_length[e] < _dist[u]) {
-            _dist[u] = _length[e];
-            _policy[u] = e;
-          }
-        }
-      }
-      return true;
-    }
-
-    // Find the minimum mean cycle in the policy graph
-    void findPolicyCycle() {
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        _level[(*_nodes)[i]] = -1;
-      }
-      LargeValue clength;
-      int csize;
-      Node u, v;
-      _curr_found = false;
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        u = (*_nodes)[i];
-        if (_level[u] >= 0) continue;
-        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
-          _level[u] = i;
-        }
-        if (_level[u] == i) {
-          // A cycle is found
-          clength = _length[_policy[u]];
-          csize = 1;
-          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
-            clength += _length[_policy[v]];
-            ++csize;
-          }
-          if ( !_curr_found ||
-               (clength * _curr_size < _curr_length * csize) ) {
-            _curr_found = true;
-            _curr_length = clength;
-            _curr_size = csize;
-            _curr_node = u;
-          }
-        }
-      }
-    }
-
-    // Contract the policy graph and compute node distances
-    bool computeNodeDistances() {
-      // Find the component of the main cycle and compute node distances
-      // using reverse BFS
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        _reached[(*_nodes)[i]] = false;
-      }
-      _qfront = _qback = 0;
-      _queue[0] = _curr_node;
-      _reached[_curr_node] = true;
-      _dist[_curr_node] = 0;
-      Node u, v;
-      Arc e;
-      while (_qfront <= _qback) {
-        v = _queue[_qfront++];
-        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
-          e = _in_arcs[v][j];
-          u = _gr.source(e);
-          if (_policy[u] == e && !_reached[u]) {
-            _reached[u] = true;
-            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
-            _queue[++_qback] = u;
-          }
-        }
-      }
-
-      // Connect all other nodes to this component and compute node
-      // distances using reverse BFS
-      _qfront = 0;
-      while (_qback < int(_nodes->size())-1) {
-        v = _queue[_qfront++];
-        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
-          e = _in_arcs[v][j];
-          u = _gr.source(e);
-          if (!_reached[u]) {
-            _reached[u] = true;
-            _policy[u] = e;
-            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
-            _queue[++_qback] = u;
-          }
-        }
-      }
-
-      // Improve node distances
-      bool improved = false;
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        v = (*_nodes)[i];
-        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
-          e = _in_arcs[v][j];
-          u = _gr.source(e);
-          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
-          if (_tolerance.less(delta, _dist[u])) {
-            _dist[u] = delta;
-            _policy[u] = e;
-            improved = true;
-          }
-        }
-      }
-      return improved;
-    }
-
-  }; //class Howard
-
-  ///@}
-
-} //namespace lemon
-
-#endif //LEMON_HOWARD_H
Index: lemon/howard_mmc.h
===================================================================
--- lemon/howard_mmc.h	(revision 956)
+++ lemon/howard_mmc.h	(revision 956)
@@ -0,0 +1,605 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HOWARD_MMC_H
+#define LEMON_HOWARD_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Howard's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HowardMmc class.
+  ///
+  /// Default traits class of HowardMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HowardMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HowardMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Howard's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Howard's policy iteration algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// This class provides the most efficient algorithm for the
+  /// minimum mean cycle problem, though the best known theoretical
+  /// bound on its running time is exponential.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
+  /// "HowardMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HowardMmcDefaultTraits<GR, CM> >
+#endif
+  class HowardMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref HowardMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Internal data used by the algorithm
+    typename Digraph::template NodeMap<Arc> _policy;
+    typename Digraph::template NodeMap<bool> _reached;
+    typename Digraph::template NodeMap<int> _level;
+    typename Digraph::template NodeMap<LargeCost> _dist;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
+
+    // Queue used for BFS search
+    std::vector<Node> _queue;
+    int _qfront, _qback;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public HowardMmc<GR, CM, SetPathTraits<T> > {
+      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HowardMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HowardMmc( const Digraph &digraph,
+               const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _best_found(false),
+      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
+      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
+      _comp(digraph), _in_arcs(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HowardMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addBack()
+    /// "addBack()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialize and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        // Find the minimum mean cycle in the current component
+        if (!buildPolicyGraph(comp)) continue;
+        while (true) {
+          findPolicyCycle();
+          if (!computeNodeDistances()) break;
+        }
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+        }
+      }
+      return _best_found;
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      _cycle_path->addBack(_policy[_best_node]);
+      for ( Node v = _best_node;
+            (v = _gr.target(_policy[v])) != _best_node; ) {
+        _cycle_path->addBack(_policy[v]);
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialize
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _queue.resize(countNodes(_gr));
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _in_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            _in_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Build the policy graph in the given strongly connected component
+    // (the out-degree of every node is 1)
+    bool buildPolicyGraph(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      if (_nodes->size() < 1 ||
+          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _dist[(*_nodes)[i]] = INF;
+      }
+      Node u, v;
+      Arc e;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_cost[e] < _dist[u]) {
+            _dist[u] = _cost[e];
+            _policy[u] = e;
+          }
+        }
+      }
+      return true;
+    }
+
+    // Find the minimum mean cycle in the policy graph
+    void findPolicyCycle() {
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _level[(*_nodes)[i]] = -1;
+      }
+      LargeCost ccost;
+      int csize;
+      Node u, v;
+      _curr_found = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        if (_level[u] >= 0) continue;
+        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
+          _level[u] = i;
+        }
+        if (_level[u] == i) {
+          // A cycle is found
+          ccost = _cost[_policy[u]];
+          csize = 1;
+          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
+            ccost += _cost[_policy[v]];
+            ++csize;
+          }
+          if ( !_curr_found ||
+               (ccost * _curr_size < _curr_cost * csize) ) {
+            _curr_found = true;
+            _curr_cost = ccost;
+            _curr_size = csize;
+            _curr_node = u;
+          }
+        }
+      }
+    }
+
+    // Contract the policy graph and compute node distances
+    bool computeNodeDistances() {
+      // Find the component of the main cycle and compute node distances
+      // using reverse BFS
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _reached[(*_nodes)[i]] = false;
+      }
+      _qfront = _qback = 0;
+      _queue[0] = _curr_node;
+      _reached[_curr_node] = true;
+      _dist[_curr_node] = 0;
+      Node u, v;
+      Arc e;
+      while (_qfront <= _qback) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_policy[u] == e && !_reached[u]) {
+            _reached[u] = true;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Connect all other nodes to this component and compute node
+      // distances using reverse BFS
+      _qfront = 0;
+      while (_qback < int(_nodes->size())-1) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (!_reached[u]) {
+            _reached[u] = true;
+            _policy[u] = e;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Improve node distances
+      bool improved = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+          if (_tolerance.less(delta, _dist[u])) {
+            _dist[u] = delta;
+            _policy[u] = e;
+            improved = true;
+          }
+        }
+      }
+      return improved;
+    }
+
+  }; //class HowardMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HOWARD_MMC_H
Index: mon/karp.h
===================================================================
--- lemon/karp.h	(revision 891)
+++ 	(revision )
@@ -1,586 +1,0 @@
-/* -*- C++ -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library
- *
- * Copyright (C) 2003-2008
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_KARP_H
-#define LEMON_KARP_H
-
-/// \ingroup min_mean_cycle
-///
-/// \file
-/// \brief Karp's algorithm for finding a minimum mean cycle.
-
-#include <vector>
-#include <limits>
-#include <lemon/core.h>
-#include <lemon/path.h>
-#include <lemon/tolerance.h>
-#include <lemon/connectivity.h>
-
-namespace lemon {
-
-  /// \brief Default traits class of Karp algorithm.
-  ///
-  /// Default traits class of Karp algorithm.
-  /// \tparam GR The type of the digraph.
-  /// \tparam LEN The type of the length map.
-  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN>
-#else
-  template <typename GR, typename LEN,
-    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
-#endif
-  struct KarpDefaultTraits
-  {
-    /// The type of the digraph
-    typedef GR Digraph;
-    /// The type of the length map
-    typedef LEN LengthMap;
-    /// The type of the arc lengths
-    typedef typename LengthMap::Value Value;
-
-    /// \brief The large value type used for internal computations
-    ///
-    /// The large value type used for internal computations.
-    /// It is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    /// \c Value must be convertible to \c LargeValue.
-    typedef double LargeValue;
-
-    /// The tolerance type used for internal computations
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addFront() function.
-    typedef lemon::Path<Digraph> Path;
-  };
-
-  // Default traits class for integer value types
-  template <typename GR, typename LEN>
-  struct KarpDefaultTraits<GR, LEN, true>
-  {
-    typedef GR Digraph;
-    typedef LEN LengthMap;
-    typedef typename LengthMap::Value Value;
-#ifdef LEMON_HAVE_LONG_LONG
-    typedef long long LargeValue;
-#else
-    typedef long LargeValue;
-#endif
-    typedef lemon::Tolerance<LargeValue> Tolerance;
-    typedef lemon::Path<Digraph> Path;
-  };
-
-
-  /// \addtogroup min_mean_cycle
-  /// @{
-
-  /// \brief Implementation of Karp's algorithm for finding a minimum
-  /// mean cycle.
-  ///
-  /// This class implements Karp's algorithm for finding a directed
-  /// cycle of minimum mean length (cost) in a digraph
-  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
-  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
-  ///
-  /// \tparam GR The type of the digraph the algorithm runs on.
-  /// \tparam LEN The type of the length map. The default
-  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
-  /// \tparam TR The traits class that defines various types used by the
-  /// algorithm. By default, it is \ref KarpDefaultTraits
-  /// "KarpDefaultTraits<GR, LEN>".
-  /// In most cases, this parameter should not be set directly,
-  /// consider to use the named template parameters instead.
-#ifdef DOXYGEN
-  template <typename GR, typename LEN, typename TR>
-#else
-  template < typename GR,
-             typename LEN = typename GR::template ArcMap<int>,
-             typename TR = KarpDefaultTraits<GR, LEN> >
-#endif
-  class Karp
-  {
-  public:
-
-    /// The type of the digraph
-    typedef typename TR::Digraph Digraph;
-    /// The type of the length map
-    typedef typename TR::LengthMap LengthMap;
-    /// The type of the arc lengths
-    typedef typename TR::Value Value;
-
-    /// \brief The large value type
-    ///
-    /// The large value type used for internal computations.
-    /// By default, it is \c long \c long if the \c Value type is integer,
-    /// otherwise it is \c double.
-    typedef typename TR::LargeValue LargeValue;
-
-    /// The tolerance type
-    typedef typename TR::Tolerance Tolerance;
-
-    /// \brief The path type of the found cycles
-    ///
-    /// The path type of the found cycles.
-    /// Using the \ref KarpDefaultTraits "default traits class",
-    /// it is \ref lemon::Path "Path<Digraph>".
-    typedef typename TR::Path Path;
-
-    /// The \ref KarpDefaultTraits "traits class" of the algorithm
-    typedef TR Traits;
-
-  private:
-
-    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
-
-    // Data sturcture for path data
-    struct PathData
-    {
-      LargeValue dist;
-      Arc pred;
-      PathData(LargeValue d, Arc p = INVALID) :
-        dist(d), pred(p) {}
-    };
-
-    typedef typename Digraph::template NodeMap<std::vector<PathData> >
-      PathDataNodeMap;
-
-  private:
-
-    // The digraph the algorithm runs on
-    const Digraph &_gr;
-    // The length of the arcs
-    const LengthMap &_length;
-
-    // Data for storing the strongly connected components
-    int _comp_num;
-    typename Digraph::template NodeMap<int> _comp;
-    std::vector<std::vector<Node> > _comp_nodes;
-    std::vector<Node>* _nodes;
-    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
-
-    // Data for the found cycle
-    LargeValue _cycle_length;
-    int _cycle_size;
-    Node _cycle_node;
-
-    Path *_cycle_path;
-    bool _local_path;
-
-    // Node map for storing path data
-    PathDataNodeMap _data;
-    // The processed nodes in the last round
-    std::vector<Node> _process;
-
-    Tolerance _tolerance;
-    
-    // Infinite constant
-    const LargeValue INF;
-
-  public:
-
-    /// \name Named Template Parameters
-    /// @{
-
-    template <typename T>
-    struct SetLargeValueTraits : public Traits {
-      typedef T LargeValue;
-      typedef lemon::Tolerance<T> Tolerance;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c LargeValue type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
-    /// type. It is used for internal computations in the algorithm.
-    template <typename T>
-    struct SetLargeValue
-      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
-      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
-    };
-
-    template <typename T>
-    struct SetPathTraits : public Traits {
-      typedef T Path;
-    };
-
-    /// \brief \ref named-templ-param "Named parameter" for setting
-    /// \c %Path type.
-    ///
-    /// \ref named-templ-param "Named parameter" for setting the \c %Path
-    /// type of the found cycles.
-    /// It must conform to the \ref lemon::concepts::Path "Path" concept
-    /// and it must have an \c addFront() function.
-    template <typename T>
-    struct SetPath
-      : public Karp<GR, LEN, SetPathTraits<T> > {
-      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
-    };
-
-    /// @}
-
-  public:
-
-    /// \brief Constructor.
-    ///
-    /// The constructor of the class.
-    ///
-    /// \param digraph The digraph the algorithm runs on.
-    /// \param length The lengths (costs) of the arcs.
-    Karp( const Digraph &digraph,
-          const LengthMap &length ) :
-      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
-      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
-      _cycle_path(NULL), _local_path(false), _data(digraph),
-      INF(std::numeric_limits<LargeValue>::has_infinity ?
-          std::numeric_limits<LargeValue>::infinity() :
-          std::numeric_limits<LargeValue>::max())
-    {}
-
-    /// Destructor.
-    ~Karp() {
-      if (_local_path) delete _cycle_path;
-    }
-
-    /// \brief Set the path structure for storing the found cycle.
-    ///
-    /// This function sets an external path structure for storing the
-    /// found cycle.
-    ///
-    /// If you don't call this function before calling \ref run() or
-    /// \ref findMinMean(), it will allocate a local \ref Path "path"
-    /// structure. The destuctor deallocates this automatically
-    /// allocated object, of course.
-    ///
-    /// \note The algorithm calls only the \ref lemon::Path::addFront()
-    /// "addFront()" function of the given path structure.
-    ///
-    /// \return <tt>(*this)</tt>
-    Karp& cycle(Path &path) {
-      if (_local_path) {
-        delete _cycle_path;
-        _local_path = false;
-      }
-      _cycle_path = &path;
-      return *this;
-    }
-
-    /// \brief Set the tolerance used by the algorithm.
-    ///
-    /// This function sets the tolerance object used by the algorithm.
-    ///
-    /// \return <tt>(*this)</tt>
-    Karp& tolerance(const Tolerance& tolerance) {
-      _tolerance = tolerance;
-      return *this;
-    }
-
-    /// \brief Return a const reference to the tolerance.
-    ///
-    /// This function returns a const reference to the tolerance object
-    /// used by the algorithm.
-    const Tolerance& tolerance() const {
-      return _tolerance;
-    }
-
-    /// \name Execution control
-    /// The simplest way to execute the algorithm is to call the \ref run()
-    /// function.\n
-    /// If you only need the minimum mean length, you may call
-    /// \ref findMinMean().
-
-    /// @{
-
-    /// \brief Run the algorithm.
-    ///
-    /// This function runs the algorithm.
-    /// It can be called more than once (e.g. if the underlying digraph
-    /// and/or the arc lengths have been modified).
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
-    /// \code
-    ///   return mmc.findMinMean() && mmc.findCycle();
-    /// \endcode
-    bool run() {
-      return findMinMean() && findCycle();
-    }
-
-    /// \brief Find the minimum cycle mean.
-    ///
-    /// This function finds the minimum mean length of the directed
-    /// cycles in the digraph.
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    bool findMinMean() {
-      // Initialization and find strongly connected components
-      init();
-      findComponents();
-      
-      // Find the minimum cycle mean in the components
-      for (int comp = 0; comp < _comp_num; ++comp) {
-        if (!initComponent(comp)) continue;
-        processRounds();
-        updateMinMean();
-      }
-      return (_cycle_node != INVALID);
-    }
-
-    /// \brief Find a minimum mean directed cycle.
-    ///
-    /// This function finds a directed cycle of minimum mean length
-    /// in the digraph using the data computed by findMinMean().
-    ///
-    /// \return \c true if a directed cycle exists in the digraph.
-    ///
-    /// \pre \ref findMinMean() must be called before using this function.
-    bool findCycle() {
-      if (_cycle_node == INVALID) return false;
-      IntNodeMap reached(_gr, -1);
-      int r = _data[_cycle_node].size();
-      Node u = _cycle_node;
-      while (reached[u] < 0) {
-        reached[u] = --r;
-        u = _gr.source(_data[u][r].pred);
-      }
-      r = reached[u];
-      Arc e = _data[u][r].pred;
-      _cycle_path->addFront(e);
-      _cycle_length = _length[e];
-      _cycle_size = 1;
-      Node v;
-      while ((v = _gr.source(e)) != u) {
-        e = _data[v][--r].pred;
-        _cycle_path->addFront(e);
-        _cycle_length += _length[e];
-        ++_cycle_size;
-      }
-      return true;
-    }
-
-    /// @}
-
-    /// \name Query Functions
-    /// The results of the algorithm can be obtained using these
-    /// functions.\n
-    /// The algorithm should be executed before using them.
-
-    /// @{
-
-    /// \brief Return the total length of the found cycle.
-    ///
-    /// This function returns the total length of the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    LargeValue cycleLength() const {
-      return _cycle_length;
-    }
-
-    /// \brief Return the number of arcs on the found cycle.
-    ///
-    /// This function returns the number of arcs on the found cycle.
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    int cycleArcNum() const {
-      return _cycle_size;
-    }
-
-    /// \brief Return the mean length of the found cycle.
-    ///
-    /// This function returns the mean length of the found cycle.
-    ///
-    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
-    /// following code.
-    /// \code
-    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
-    /// \endcode
-    ///
-    /// \pre \ref run() or \ref findMinMean() must be called before
-    /// using this function.
-    double cycleMean() const {
-      return static_cast<double>(_cycle_length) / _cycle_size;
-    }
-
-    /// \brief Return the found cycle.
-    ///
-    /// This function returns a const reference to the path structure
-    /// storing the found cycle.
-    ///
-    /// \pre \ref run() or \ref findCycle() must be called before using
-    /// this function.
-    const Path& cycle() const {
-      return *_cycle_path;
-    }
-
-    ///@}
-
-  private:
-
-    // Initialization
-    void init() {
-      if (!_cycle_path) {
-        _local_path = true;
-        _cycle_path = new Path;
-      }
-      _cycle_path->clear();
-      _cycle_length = 0;
-      _cycle_size = 1;
-      _cycle_node = INVALID;
-      for (NodeIt u(_gr); u != INVALID; ++u)
-        _data[u].clear();
-    }
-
-    // Find strongly connected components and initialize _comp_nodes
-    // and _out_arcs
-    void findComponents() {
-      _comp_num = stronglyConnectedComponents(_gr, _comp);
-      _comp_nodes.resize(_comp_num);
-      if (_comp_num == 1) {
-        _comp_nodes[0].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          _comp_nodes[0].push_back(n);
-          _out_arcs[n].clear();
-          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
-            _out_arcs[n].push_back(a);
-          }
-        }
-      } else {
-        for (int i = 0; i < _comp_num; ++i)
-          _comp_nodes[i].clear();
-        for (NodeIt n(_gr); n != INVALID; ++n) {
-          int k = _comp[n];
-          _comp_nodes[k].push_back(n);
-          _out_arcs[n].clear();
-          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
-            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
-          }
-        }
-      }
-    }
-
-    // Initialize path data for the current component
-    bool initComponent(int comp) {
-      _nodes = &(_comp_nodes[comp]);
-      int n = _nodes->size();
-      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
-        return false;
-      }      
-      for (int i = 0; i < n; ++i) {
-        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
-      }
-      return true;
-    }
-
-    // Process all rounds of computing path data for the current component.
-    // _data[v][k] is the length of a shortest directed walk from the root
-    // node to node v containing exactly k arcs.
-    void processRounds() {
-      Node start = (*_nodes)[0];
-      _data[start][0] = PathData(0);
-      _process.clear();
-      _process.push_back(start);
-
-      int k, n = _nodes->size();
-      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
-        processNextBuildRound(k);
-      }
-      for ( ; k <= n; ++k) {
-        processNextFullRound(k);
-      }
-    }
-
-    // Process one round and rebuild _process
-    void processNextBuildRound(int k) {
-      std::vector<Node> next;
-      Node u, v;
-      Arc e;
-      LargeValue d;
-      for (int i = 0; i < int(_process.size()); ++i) {
-        u = _process[i];
-        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
-          e = _out_arcs[u][j];
-          v = _gr.target(e);
-          d = _data[u][k-1].dist + _length[e];
-          if (_tolerance.less(d, _data[v][k].dist)) {
-            if (_data[v][k].dist == INF) next.push_back(v);
-            _data[v][k] = PathData(d, e);
-          }
-        }
-      }
-      _process.swap(next);
-    }
-
-    // Process one round using _nodes instead of _process
-    void processNextFullRound(int k) {
-      Node u, v;
-      Arc e;
-      LargeValue d;
-      for (int i = 0; i < int(_nodes->size()); ++i) {
-        u = (*_nodes)[i];
-        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
-          e = _out_arcs[u][j];
-          v = _gr.target(e);
-          d = _data[u][k-1].dist + _length[e];
-          if (_tolerance.less(d, _data[v][k].dist)) {
-            _data[v][k] = PathData(d, e);
-          }
-        }
-      }
-    }
-
-    // Update the minimum cycle mean
-    void updateMinMean() {
-      int n = _nodes->size();
-      for (int i = 0; i < n; ++i) {
-        Node u = (*_nodes)[i];
-        if (_data[u][n].dist == INF) continue;
-        LargeValue length, max_length = 0;
-        int size, max_size = 1;
-        bool found_curr = false;
-        for (int k = 0; k < n; ++k) {
-          if (_data[u][k].dist == INF) continue;
-          length = _data[u][n].dist - _data[u][k].dist;
-          size = n - k;
-          if (!found_curr || length * max_size > max_length * size) {
-            found_curr = true;
-            max_length = length;
-            max_size = size;
-          }
-        }
-        if ( found_curr && (_cycle_node == INVALID ||
-             max_length * _cycle_size < _cycle_length * max_size) ) {
-          _cycle_length = max_length;
-          _cycle_size = max_size;
-          _cycle_node = u;
-        }
-      }
-    }
-
-  }; //class Karp
-
-  ///@}
-
-} //namespace lemon
-
-#endif //LEMON_KARP_H
Index: lemon/karp_mmc.h
===================================================================
--- lemon/karp_mmc.h	(revision 956)
+++ lemon/karp_mmc.h	(revision 956)
@@ -0,0 +1,590 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_KARP_MMC_H
+#define LEMON_KARP_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Karp's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of KarpMmc class.
+  ///
+  /// Default traits class of KarpMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct KarpMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct KarpMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Karp's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Karp's algorithm for finding a directed
+  /// cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
+  /// "KarpMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = KarpMmcDefaultTraits<GR, CM> >
+#endif
+  class KarpMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref KarpMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycle
+    LargeCost _cycle_cost;
+    int _cycle_size;
+    Node _cycle_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public KarpMmc<GR, CM, SetPathTraits<T> > {
+      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    KarpMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    KarpMmc( const Digraph &digraph,
+             const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~KarpMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+        updateMinMean();
+      }
+      return (_cycle_node != INVALID);
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (_cycle_node == INVALID) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _data[_cycle_node].size();
+      Node u = _cycle_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _cycle_cost = _cost[e];
+      _cycle_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _cycle_cost += _cost[e];
+        ++_cycle_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_cycle_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _cycle_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_cycle_cost) / _cycle_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _cycle_cost = 0;
+      _cycle_size = 1;
+      _cycle_node = INVALID;
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
+        processNextBuildRound(k);
+      }
+      for ( ; k <= n; ++k) {
+        processNextFullRound(k);
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Update the minimum cycle mean
+    void updateMinMean() {
+      int n = _nodes->size();
+      for (int i = 0; i < n; ++i) {
+        Node u = (*_nodes)[i];
+        if (_data[u][n].dist == INF) continue;
+        LargeCost cost, max_cost = 0;
+        int size, max_size = 1;
+        bool found_curr = false;
+        for (int k = 0; k < n; ++k) {
+          if (_data[u][k].dist == INF) continue;
+          cost = _data[u][n].dist - _data[u][k].dist;
+          size = n - k;
+          if (!found_curr || cost * max_size > max_cost * size) {
+            found_curr = true;
+            max_cost = cost;
+            max_size = size;
+          }
+        }
+        if ( found_curr && (_cycle_node == INVALID ||
+             max_cost * _cycle_size < _cycle_cost * max_size) ) {
+          _cycle_cost = max_cost;
+          _cycle_size = max_size;
+          _cycle_node = u;
+        }
+      }
+    }
+
+  }; //class KarpMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_KARP_MMC_H
Index: mon/kary_heap.h
===================================================================
--- lemon/kary_heap.h	(revision 753)
+++ 	(revision )
@@ -1,352 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2009
- * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
- * (Egervary Research Group on Combinatorial Optimization, EGRES).
- *
- * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
- * precise terms see the accompanying LICENSE file.
- *
- * This software is provided "AS IS" with no warranty of any kind,
- * express or implied, and with no claim as to its suitability for any
- * purpose.
- *
- */
-
-#ifndef LEMON_KARY_HEAP_H
-#define LEMON_KARY_HEAP_H
-
-///\ingroup heaps
-///\file
-///\brief Fourary heap implementation.
-
-#include <vector>
-#include <utility>
-#include <functional>
-
-namespace lemon {
-
-  /// \ingroup heaps
-  ///
-  ///\brief K-ary heap data structure.
-  ///
-  /// This class implements the \e K-ary \e heap data structure.
-  /// It fully conforms to the \ref concepts::Heap "heap concept".
-  ///
-  /// The \ref KaryHeap "K-ary heap" is a generalization of the
-  /// \ref BinHeap "binary heap" structure, its nodes have at most
-  /// \c K children, instead of two.
-  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
-  /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
-  ///
-  /// \tparam PR Type of the priorities of the items.
-  /// \tparam IM A read-writable item map with \c int values, used
-  /// internally to handle the cross references.
-  /// \tparam K The degree of the heap, each node have at most \e K
-  /// children. The default is 16. Powers of two are suggested to use
-  /// so that the multiplications and divisions needed to traverse the
-  /// nodes of the heap could be performed faster.
-  /// \tparam CMP A functor class for comparing the priorities.
-  /// The default is \c std::less<PR>.
-  ///
-  ///\sa BinHeap
-  ///\sa FouraryHeap
-#ifdef DOXYGEN
-  template <typename PR, typename IM, int K, typename CMP>
-#else
-  template <typename PR, typename IM, int K = 16,
-            typename CMP = std::less<PR> >
-#endif
-  class KaryHeap {
-  public:
-    /// Type of the item-int map.
-    typedef IM ItemIntMap;
-    /// Type of the priorities.
-    typedef PR Prio;
-    /// Type of the items stored in the heap.
-    typedef typename ItemIntMap::Key Item;
-    /// Type of the item-priority pairs.
-    typedef std::pair<Item,Prio> Pair;
-    /// Functor type for comparing the priorities.
-    typedef CMP Compare;
-
-    /// \brief Type to represent the states of the items.
-    ///
-    /// Each item has a state associated to it. It can be "in heap",
-    /// "pre-heap" or "post-heap". The latter two are indifferent from the
-    /// heap's point of view, but may be useful to the user.
-    ///
-    /// The item-int map must be initialized in such way that it assigns
-    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
-    enum State {
-      IN_HEAP = 0,    ///< = 0.
-      PRE_HEAP = -1,  ///< = -1.
-      POST_HEAP = -2  ///< = -2.
-    };
-
-  private:
-    std::vector<Pair> _data;
-    Compare _comp;
-    ItemIntMap &_iim;
-
-  public:
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
-
-    /// \brief Constructor.
-    ///
-    /// Constructor.
-    /// \param map A map that assigns \c int values to the items.
-    /// It is used internally to handle the cross references.
-    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
-    /// \param comp The function object used for comparing the priorities.
-    KaryHeap(ItemIntMap &map, const Compare &comp)
-      : _iim(map), _comp(comp) {}
-
-    /// \brief The number of items stored in the heap.
-    ///
-    /// This function returns the number of items stored in the heap.
-    int size() const { return _data.size(); }
-
-    /// \brief Check if the heap is empty.
-    ///
-    /// This function returns \c true if the heap is empty.
-    bool empty() const { return _data.empty(); }
-
-    /// \brief Make the heap empty.
-    ///
-    /// This functon makes the heap empty.
-    /// It does not change the cross reference map. If you want to reuse
-    /// a heap that is not surely empty, you should first clear it and
-    /// then you should set the cross reference map to \c PRE_HEAP
-    /// for each item.
-    void clear() { _data.clear(); }
-
-  private:
-    int parent(int i) { return (i-1)/K; }
-    int firstChild(int i) { return K*i+1; }
-
-    bool less(const Pair &p1, const Pair &p2) const {
-      return _comp(p1.second, p2.second);
-    }
-
-    void bubbleUp(int hole, Pair p) {
-      int par = parent(hole);
-      while( hole>0 && less(p,_data[par]) ) {
-        move(_data[par],hole);
-        hole = par;
-        par = parent(hole);
-      }
-      move(p, hole);
-    }
-
-    void bubbleDown(int hole, Pair p, int length) {
-      if( length>1 ) {
-        int child = firstChild(hole);
-        while( child+K<=length ) {
-          int min=child;
-          for (int i=1; i<K; ++i) {
-            if( less(_data[child+i], _data[min]) )
-              min=child+i;
-          }
-          if( !less(_data[min], p) )
-            goto ok;
-          move(_data[min], hole);
-          hole = min;
-          child = firstChild(hole);
-        }
-        if ( child<length ) {
-          int min = child;
-          while (++child < length) {
-            if( less(_data[child], _data[min]) )
-              min=child;
-          }
-          if( less(_data[min], p) ) {
-            move(_data[min], hole);
-            hole = min;
-          }
-        }
-      }
-    ok:
-      move(p, hole);
-    }
-
-    void move(const Pair &p, int i) {
-      _data[i] = p;
-      _iim.set(p.first, i);
-    }
-
-  public:
-    /// \brief Insert a pair of item and priority into the heap.
-    ///
-    /// This function inserts \c p.first to the heap with priority
-    /// \c p.second.
-    /// \param p The pair to insert.
-    /// \pre \c p.first must not be stored in the heap.
-    void push(const Pair &p) {
-      int n = _data.size();
-      _data.resize(n+1);
-      bubbleUp(n, p);
-    }
-
-    /// \brief Insert an item into the heap with the given priority.
-    ///
-    /// This function inserts the given item into the heap with the
-    /// given priority.
-    /// \param i The item to insert.
-    /// \param p The priority of the item.
-    /// \pre \e i must not be stored in the heap.
-    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
-
-    /// \brief Return the item having minimum priority.
-    ///
-    /// This function returns the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    Item top() const { return _data[0].first; }
-
-    /// \brief The minimum priority.
-    ///
-    /// This function returns the minimum priority.
-    /// \pre The heap must be non-empty.
-    Prio prio() const { return _data[0].second; }
-
-    /// \brief Remove the item having minimum priority.
-    ///
-    /// This function removes the item having minimum priority.
-    /// \pre The heap must be non-empty.
-    void pop() {
-      int n = _data.size()-1;
-      _iim.set(_data[0].first, POST_HEAP);
-      if (n>0) bubbleDown(0, _data[n], n);
-      _data.pop_back();
-    }
-
-    /// \brief Remove the given item from the heap.
-    ///
-    /// This function removes the given item from the heap if it is
-    /// already stored.
-    /// \param i The item to delete.
-    /// \pre \e i must be in the heap.
-    void erase(const Item &i) {
-      int h = _iim[i];
-      int n = _data.size()-1;
-      _iim.set(_data[h].first, POST_HEAP);
-      if( h<n ) {
-        if( less(_data[parent(h)], _data[n]) )
-          bubbleDown(h, _data[n], n);
-        else
-          bubbleUp(h, _data[n]);
-      }
-      _data.pop_back();
-    }
-
-    /// \brief The priority of the given item.
-    ///
-    /// This function returns the priority of the given item.
-    /// \param i The item.
-    /// \pre \e i must be in the heap.
-    Prio operator[](const Item &i) const {
-      int idx = _iim[i];
-      return _data[idx].second;
-    }
-
-    /// \brief Set the priority of an item or insert it, if it is
-    /// not stored in the heap.
-    ///
-    /// This method sets the priority of the given item if it is
-    /// already stored in the heap. Otherwise it inserts the given
-    /// item into the heap with the given priority.
-    /// \param i The item.
-    /// \param p The priority.
-    void set(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      if( idx<0 )
-        push(i,p);
-      else if( _comp(p, _data[idx].second) )
-        bubbleUp(idx, Pair(i,p));
-      else
-        bubbleDown(idx, Pair(i,p), _data.size());
-    }
-
-    /// \brief Decrease the priority of an item to the given value.
-    ///
-    /// This function decreases the priority of an item to the given value.
-    /// \param i The item.
-    /// \param p The priority.
-    /// \pre \e i must be stored in the heap with priority at least \e p.
-    void decrease(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      bubbleUp(idx, Pair(i,p));
-    }
-
-    /// \brief Increase the priority of an item to the given value.
-    ///
-    /// This function increases the priority of an item to the given value.
-    /// \param i The item.
-    /// \param p The priority.
-    /// \pre \e i must be stored in the heap with priority at most \e p.
-    void increase(const Item &i, const Prio &p) {
-      int idx = _iim[i];
-      bubbleDown(idx, Pair(i,p), _data.size());
-    }
-
-    /// \brief Return the state of an item.
-    ///
-    /// This method returns \c PRE_HEAP if the given item has never
-    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
-    /// and \c POST_HEAP otherwise.
-    /// In the latter case it is possible that the item will get back
-    /// to the heap again.
-    /// \param i The item.
-    State state(const Item &i) const {
-      int s = _iim[i];
-      if (s>=0) s=0;
-      return State(s);
-    }
-
-    /// \brief Set the state of an item in the heap.
-    ///
-    /// This function sets the state of the given item in the heap.
-    /// It can be used to manually clear the heap when it is important
-    /// to achive better time complexity.
-    /// \param i The item.
-    /// \param st The state. It should not be \c IN_HEAP.
-    void state(const Item& i, State st) {
-      switch (st) {
-        case POST_HEAP:
-        case PRE_HEAP:
-          if (state(i) == IN_HEAP) erase(i);
-          _iim[i] = st;
-          break;
-        case IN_HEAP:
-          break;
-      }
-    }
-
-    /// \brief Replace an item in the heap.
-    ///
-    /// This function replaces item \c i with item \c j.
-    /// Item \c i must be in the heap, while \c j must be out of the heap.
-    /// After calling this method, item \c i will be out of the
-    /// heap and \c j will be in the heap with the same prioriority
-    /// as item \c i had before.
-    void replace(const Item& i, const Item& j) {
-      int idx=_iim[i];
-      _iim.set(i, _iim[j]);
-      _iim.set(j, idx);
-      _data[idx].first=j;
-    }
-
-  }; // class KaryHeap
-
-} // namespace lemon
-
-#endif // LEMON_KARY_HEAP_H
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 833)
+++ lemon/lgf_reader.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -563,5 +563,5 @@
     friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
     template <typename TDGR>
-    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
                                              const std::string& fn);
     template <typename TDGR>
@@ -1188,5 +1188,5 @@
 
   };
-  
+
   /// \ingroup lemon_io
   ///
@@ -1195,5 +1195,5 @@
   /// This function just returns a \ref DigraphReader class.
   ///
-  /// With this function a digraph can be read from an 
+  /// With this function a digraph can be read from an
   /// \ref lgf-format "LGF" file or input stream with several maps and
   /// attributes. For example, there is network flow problem on a
@@ -1250,5 +1250,5 @@
   template <typename GR>
   class GraphReader;
- 
+
   template <typename TGR>
   GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
@@ -1387,5 +1387,5 @@
     friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
     template <typename TGR>
-    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
+    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
     template <typename TGR>
     friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
@@ -2064,7 +2064,7 @@
   /// \brief Return a \ref GraphReader class
   ///
-  /// This function just returns a \ref GraphReader class. 
-  ///
-  /// With this function a graph can be read from an 
+  /// This function just returns a \ref GraphReader class.
+  ///
+  /// With this function a graph can be read from an
   /// \ref lgf-format "LGF" file or input stream with several maps and
   /// attributes. For example, there is weighted matching problem on a
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 646)
+++ lemon/lgf_writer.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -352,5 +352,5 @@
 
   template <typename TDGR>
-  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
                                    std::ostream& os = std::cout);
   template <typename TDGR>
@@ -505,5 +505,5 @@
 
     template <typename TDGR>
-    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
                                              std::ostream& os);
     template <typename TDGR>
@@ -918,5 +918,5 @@
   /// \brief Return a \ref DigraphWriter class
   ///
-  /// This function just returns a \ref DigraphWriter class. 
+  /// This function just returns a \ref DigraphWriter class.
   ///
   /// With this function a digraph can be write to a file or output
@@ -958,5 +958,5 @@
   /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
   template <typename TDGR>
-  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
                                     const std::string& fn) {
     DigraphWriter<TDGR> tmp(digraph, fn);
@@ -1102,9 +1102,9 @@
     friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
     template <typename TGR>
-    friend GraphWriter<TGR> graphWriter(const TGR& graph, 
+    friend GraphWriter<TGR> graphWriter(const TGR& graph,
                                         const std::string& fn);
     template <typename TGR>
     friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
-    
+
     GraphWriter(GraphWriter& other)
       : _os(other._os), local_os(other.local_os), _graph(other._graph),
@@ -1557,5 +1557,5 @@
   /// \brief Return a \ref GraphWriter class
   ///
-  /// This function just returns a \ref GraphWriter class. 
+  /// This function just returns a \ref GraphWriter class.
   ///
   /// With this function a graph can be write to a file or output
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 835)
+++ lemon/list_graph.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -447,5 +447,5 @@
     ///invalidated for the outgoing arcs of node \c v and \c InArcIt
     ///iterators are invalidated for the incomming arcs of \c v.
-    ///Moreover all iterators referencing node \c v or the removed 
+    ///Moreover all iterators referencing node \c v or the removed
     ///loops are also invalidated. Other iterators remain valid.
     ///
@@ -553,5 +553,5 @@
     /// restore() function.
     ///
-    /// \note After a state is restored, you cannot restore a later state, 
+    /// \note After a state is restored, you cannot restore a later state,
     /// i.e. you cannot add the removed nodes and arcs again using
     /// another Snapshot instance.
@@ -1308,5 +1308,5 @@
     /// or changeV(), thus all edge and arc iterators whose base node is
     /// \c b are invalidated.
-    /// Moreover all iterators referencing node \c b or the removed 
+    /// Moreover all iterators referencing node \c b or the removed
     /// loops are also invalidated. Other iterators remain valid.
     ///
@@ -1365,5 +1365,5 @@
     /// using the restore() function.
     ///
-    /// \note After a state is restored, you cannot restore a later state, 
+    /// \note After a state is restored, you cannot restore a later state,
     /// i.e. you cannot add the removed nodes and edges again using
     /// another Snapshot instance.
Index: lemon/lp.h
===================================================================
--- lemon/lp.h	(revision 674)
+++ lemon/lp.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -85,5 +85,5 @@
 #elif LEMON_HAVE_CLP
 # define DEFAULT_LP CLP
-  typedef ClpLp Lp;  
+  typedef ClpLp Lp;
 #endif
 #endif
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 557)
+++ lemon/lp_base.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 903)
+++ lemon/lp_base.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -83,5 +83,5 @@
       MESSAGE_VERBOSE
     };
-    
+
 
     ///The floating point type used by the solver
@@ -115,12 +115,12 @@
       typedef True LpCol;
       /// Default constructor
-      
+
       /// \warning The default constructor sets the Col to an
       /// undefined value.
       Col() {}
       /// Invalid constructor \& conversion.
-      
+
       /// This constructor initializes the Col to be invalid.
-      /// \sa Invalid for more details.      
+      /// \sa Invalid for more details.
       Col(const Invalid&) : _id(-1) {}
       /// Equality operator
@@ -157,10 +157,10 @@
     public:
       /// Default constructor
-      
+
       /// \warning The default constructor sets the iterator
       /// to an undefined value.
       ColIt() {}
       /// Sets the iterator to the first Col
-      
+
       /// Sets the iterator to the first Col.
       ///
@@ -170,10 +170,10 @@
       }
       /// Invalid constructor \& conversion
-      
+
       /// Initialize the iterator to be invalid.
       /// \sa Invalid for more details.
       ColIt(const Invalid&) : Col(INVALID) {}
       /// Next column
-      
+
       /// Assign the iterator to the next column.
       ///
@@ -210,12 +210,12 @@
       typedef True LpRow;
       /// Default constructor
-      
+
       /// \warning The default constructor sets the Row to an
       /// undefined value.
       Row() {}
       /// Invalid constructor \& conversion.
-      
+
       /// This constructor initializes the Row to be invalid.
-      /// \sa Invalid for more details.      
+      /// \sa Invalid for more details.
       Row(const Invalid&) : _id(-1) {}
       /// Equality operator
@@ -225,5 +225,5 @@
       bool operator==(Row r) const  {return _id == r._id;}
       /// Inequality operator
-      
+
       /// \sa operator==(Row r)
       ///
@@ -252,10 +252,10 @@
     public:
       /// Default constructor
-      
+
       /// \warning The default constructor sets the iterator
       /// to an undefined value.
       RowIt() {}
       /// Sets the iterator to the first Row
-      
+
       /// Sets the iterator to the first Row.
       ///
@@ -265,10 +265,10 @@
       }
       /// Invalid constructor \& conversion
-      
+
       /// Initialize the iterator to be invalid.
       /// \sa Invalid for more details.
       RowIt(const Invalid&) : Row(INVALID) {}
       /// Next row
-      
+
       /// Assign the iterator to the next row.
       ///
@@ -348,5 +348,5 @@
       typedef True SolverExpr;
       /// Default constructor
-      
+
       /// Construct an empty expression, the coefficients and
       /// the constant component are initialized to zero.
@@ -449,7 +449,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -465,5 +465,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -482,5 +482,5 @@
         const Value& operator*() const { return _it->second; }
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -494,7 +494,7 @@
 
       /// Const iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -510,5 +510,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -525,5 +525,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -674,5 +674,5 @@
       typedef True SolverExpr;
       /// Default constructor
-      
+
       /// Construct an empty expression, the coefficients are
       /// initialized to zero.
@@ -709,5 +709,5 @@
       }
       /// \brief Removes the coefficients which's absolute value does
-      /// not exceed \c epsilon. 
+      /// not exceed \c epsilon.
       void simplify(Value epsilon = 0.0) {
         std::map<int, Value>::iterator it=comps.begin();
@@ -758,7 +758,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -774,5 +774,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -792,5 +792,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -804,7 +804,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -820,5 +820,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -835,5 +835,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -1230,5 +1230,5 @@
       Row r;
       c.expr().simplify();
-      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF, 
+      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
                                 ExprIterator(c.expr().comps.begin(), cols),
                                 ExprIterator(c.expr().comps.end(), cols),
@@ -1818,8 +1818,8 @@
     enum VarStatus {
       /// The variable is in the basis
-      BASIC, 
+      BASIC,
       /// The variable is free, but not basic
       FREE,
-      /// The variable has active lower bound 
+      /// The variable has active lower bound
       LOWER,
       /// The variable has active upper bound
@@ -1900,5 +1900,5 @@
     }
     /// Returns a component of the primal ray
-    
+
     /// The primal ray is solution of the modified primal problem,
     /// where we change each finite bound to 0, and we looking for a
@@ -1934,5 +1934,5 @@
 
     /// Returns a component of the dual ray
-    
+
     /// The dual ray is solution of the modified primal problem, where
     /// we change each finite bound to 0 (i.e. the objective function
@@ -2076,5 +2076,5 @@
     }
     ///The value of the objective function
-    
+
     ///\return
     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 793)
+++ lemon/lp_skeleton.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 793)
+++ lemon/lp_skeleton.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,5 +24,5 @@
 ///\file
 ///\brief Skeleton file to implement LP/MIP solver interfaces
-///  
+///
 ///The classes in this file do nothing, but they can serve as skeletons when
 ///implementing an interface to new solvers.
@@ -30,5 +30,5 @@
 
   ///A skeleton class to implement LP/MIP solver base interface
-  
+
   ///This class does nothing, but it can serve as a skeleton when
   ///implementing an interface to new solvers.
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 839)
+++ lemon/maps.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -234,5 +234,5 @@
   /// heap types and \c UnionFind, when the used items are small
   /// integers. This map conforms to the \ref concepts::ReferenceMap
-  /// "ReferenceMap" concept. 
+  /// "ReferenceMap" concept.
   ///
   /// The simplest way of using this map is through the rangeMap()
@@ -1917,9 +1917,9 @@
   /// \c InverseMap or \c operator()(), and the values of the map can be
   /// accessed with an STL compatible forward iterator (\c ValueIt).
-  /// 
+  ///
   /// This map is intended to be used when all associated values are
   /// different (the map is actually invertable) or there are only a few
   /// items with the same value.
-  /// Otherwise consider to use \c IterableValueMap, which is more 
+  /// Otherwise consider to use \c IterableValueMap, which is more
   /// suitable and more efficient for such cases. It provides iterators
   /// to traverse the items with the same associated value, but
@@ -2003,5 +2003,5 @@
       typename Container::const_iterator it;
     };
-    
+
     /// Alias for \c ValueIt
     typedef ValueIt ValueIterator;
@@ -2062,5 +2062,5 @@
       return it != _inv_map.end() ? it->second : INVALID;
     }
-    
+
     /// \brief Returns the number of items with the given value.
     ///
@@ -2379,5 +2379,5 @@
     return RangeIdMap<GR, K>(graph);
   }
-  
+
   /// \brief Dynamic iterable \c bool map.
   ///
@@ -2639,5 +2639,5 @@
       /// \param value The value.
       ItemIt(const IterableBoolMap& map, bool value)
-        : Parent(value ? 
+        : Parent(value ?
                  (map._sep > 0 ?
                   map._array[map._sep - 1] : INVALID) :
@@ -3787,5 +3787,5 @@
     typedef typename To::Key Item;
     typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
-    
+
     for (ItemIt it(gr); it != INVALID; ++it) {
       to.set(it, from[it]);
@@ -3795,5 +3795,5 @@
   /// \brief Compare two graph maps.
   ///
-  /// This function compares the values of two graph maps. It returns 
+  /// This function compares the values of two graph maps. It returns
   /// \c true if the maps assign the same value for all items in the graph.
   /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
@@ -3807,5 +3807,5 @@
     typedef typename Map2::Key Item;
     typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
-    
+
     for (ItemIt it(gr); it != INVALID; ++it) {
       if (!(map1[it] == map2[it])) return false;
Index: lemon/matching.h
===================================================================
--- lemon/matching.h	(revision 698)
+++ lemon/matching.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,6 +17,6 @@
  */
 
-#ifndef LEMON_MAX_MATCHING_H
-#define LEMON_MAX_MATCHING_H
+#ifndef LEMON_MATCHING_H
+#define LEMON_MATCHING_H
 
 #include <vector>
@@ -29,4 +29,5 @@
 #include <lemon/bin_heap.h>
 #include <lemon/maps.h>
+#include <lemon/fractional_matching.h>
 
 ///\ingroup matching
@@ -42,5 +43,5 @@
   /// This class implements Edmonds' alternating forest matching algorithm
   /// for finding a maximum cardinality matching in a general undirected graph.
-  /// It can be started from an arbitrary initial matching 
+  /// It can be started from an arbitrary initial matching
   /// (the default is the empty one).
   ///
@@ -70,9 +71,9 @@
     ///\brief Status constants for Gallai-Edmonds decomposition.
     ///
-    ///These constants are used for indicating the Gallai-Edmonds 
+    ///These constants are used for indicating the Gallai-Edmonds
     ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
     ///induce a subgraph with factor-critical components, the nodes with
     ///status \c ODD (or \c A) form the canonical barrier, and the nodes
-    ///with status \c MATCHED (or \c C) induce a subgraph having a 
+    ///with status \c MATCHED (or \c C) induce a subgraph having a
     ///perfect matching.
     enum Status {
@@ -513,5 +514,5 @@
     }
 
-    /// \brief Start Edmonds' algorithm with a heuristic improvement 
+    /// \brief Start Edmonds' algorithm with a heuristic improvement
     /// for dense graphs
     ///
@@ -535,6 +536,6 @@
     /// \brief Run Edmonds' algorithm
     ///
-    /// This function runs Edmonds' algorithm. An additional heuristic of 
-    /// postponing shrinks is used for relatively dense graphs 
+    /// This function runs Edmonds' algorithm. An additional heuristic of
+    /// postponing shrinks is used for relatively dense graphs
     /// (for which <tt>m>=2*n</tt> holds).
     void run() {
@@ -557,5 +558,5 @@
     /// \brief Return the size (cardinality) of the matching.
     ///
-    /// This function returns the size (cardinality) of the current matching. 
+    /// This function returns the size (cardinality) of the current matching.
     /// After run() it returns the size of the maximum matching in the graph.
     int matchingSize() const {
@@ -571,5 +572,5 @@
     /// \brief Return \c true if the given edge is in the matching.
     ///
-    /// This function returns \c true if the given edge is in the current 
+    /// This function returns \c true if the given edge is in the current
     /// matching.
     bool matching(const Edge& edge) const {
@@ -580,5 +581,5 @@
     ///
     /// This function returns the matching arc (or edge) incident to the
-    /// given node in the current matching or \c INVALID if the node is 
+    /// given node in the current matching or \c INVALID if the node is
     /// not covered by the matching.
     Arc matching(const Node& n) const {
@@ -596,5 +597,5 @@
     /// \brief Return the mate of the given node.
     ///
-    /// This function returns the mate of the given node in the current 
+    /// This function returns the mate of the given node in the current
     /// matching or \c INVALID if the node is not covered by the matching.
     Node mate(const Node& n) const {
@@ -606,5 +607,5 @@
 
     /// \name Dual Solution
-    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
+    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
     /// decomposition.
 
@@ -649,6 +650,6 @@
   /// \f$O(nm\log n)\f$ time complexity.
   ///
-  /// The maximum weighted matching problem is to find a subset of the 
-  /// edges in an undirected graph with maximum overall weight for which 
+  /// The maximum weighted matching problem is to find a subset of the
+  /// edges in an undirected graph with maximum overall weight for which
   /// each node has at most one incident edge.
   /// It can be formulated with the following linear program.
@@ -674,14 +675,14 @@
       \frac{\vert B \vert - 1}{2}z_B\f] */
   ///
-  /// The algorithm can be executed with the run() function. 
+  /// The algorithm can be executed with the run() function.
   /// After it the matching (the primal solution) and the dual solution
-  /// can be obtained using the query functions and the 
-  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
-  /// which is able to iterate on the nodes of a blossom. 
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
   /// If the value type is integer, then the dual solution is multiplied
   /// by \ref MaxWeightedMatching::dualScale "4".
   ///
   /// \tparam GR The undirected graph type the algorithm runs on.
-  /// \tparam WM The type edge weight map. The default type is 
+  /// \tparam WM The type edge weight map. The default type is
   /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 #ifdef DOXYGEN
@@ -746,5 +747,5 @@
 
     enum Status {
-      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
+      EVEN = -1, MATCHED = 0, ODD = 1
     };
 
@@ -798,4 +799,8 @@
 
     Value _delta_sum;
+    int _unmatched;
+
+    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
+    FractionalMatching *_fractional;
 
     void createStructures() {
@@ -806,11 +811,16 @@
         _matching = new MatchingMap(_graph);
       }
+
       if (!_node_potential) {
         _node_potential = new NodePotential(_graph);
       }
+
       if (!_blossom_set) {
         _blossom_index = new IntNodeMap(_graph);
         _blossom_set = new BlossomSet(*_blossom_index);
         _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
       }
 
@@ -819,5 +829,9 @@
         _node_heap_index = new IntArcMap(_graph);
         _node_data = new RangeMap<NodeData>(_node_num,
-                                              NodeData(*_node_heap_index));
+                                            NodeData(*_node_heap_index));
+      } else {
+        delete _node_data;
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
       }
 
@@ -825,27 +839,34 @@
         _tree_set_index = new IntIntMap(_blossom_num);
         _tree_set = new TreeSet(*_tree_set_index);
-      }
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
       if (!_delta1) {
         _delta1_index = new IntNodeMap(_graph);
         _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
       }
+
       if (!_delta2) {
         _delta2_index = new IntIntMap(_blossom_num);
         _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
-      }
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
       if (!_delta3) {
         _delta3_index = new IntEdgeMap(_graph);
         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
       }
+
       if (!_delta4) {
         _delta4_index = new IntIntMap(_blossom_num);
         _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      } else {
+        _delta4_index->resize(_blossom_num);
       }
     }
 
     void destroyStructures() {
-      _node_num = countNodes(_graph);
-      _blossom_num = _node_num * 3 / 2;
-
       if (_matching) {
         delete _matching;
@@ -922,8 +943,4 @@
             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
               _delta3->push(e, rw / 2);
-            }
-          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
-            if (_delta3->state(e) != _delta3->IN_HEAP) {
-              _delta3->push(e, rw);
             }
           } else {
@@ -950,5 +967,5 @@
                                (*_blossom_data)[vb].offset);
                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
-                           (*_blossom_data)[vb].offset){
+                           (*_blossom_data)[vb].offset) {
                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
                                    (*_blossom_data)[vb].offset);
@@ -969,5 +986,5 @@
       if (!_blossom_set->trivial(blossom)) {
         _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
-                     (*_blossom_data)[blossom].offset);
+                      (*_blossom_data)[blossom].offset);
       }
     }
@@ -1036,9 +1053,4 @@
                 }
               }
-            }
-
-          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
-            if (_delta3->state(e) == _delta3->IN_HEAP) {
-              _delta3->erase(e);
             }
           } else {
@@ -1078,5 +1090,5 @@
           std::numeric_limits<Value>::max()) {
         _delta2->push(blossom, _blossom_set->classPrio(blossom) -
-                       (*_blossom_data)[blossom].offset);
+                      (*_blossom_data)[blossom].offset);
       }
 
@@ -1117,8 +1129,4 @@
             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
               _delta3->push(e, rw / 2);
-            }
-          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
-            if (_delta3->state(e) != _delta3->IN_HEAP) {
-              _delta3->push(e, rw);
             }
           } else {
@@ -1158,99 +1166,4 @@
     }
 
-
-    void matchedToUnmatched(int blossom) {
-      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
-        _delta2->erase(blossom);
-      }
-
-      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
-           n != INVALID; ++n) {
-        int ni = (*_node_index)[n];
-
-        _blossom_set->increase(n, std::numeric_limits<Value>::max());
-
-        (*_node_data)[ni].heap.clear();
-        (*_node_data)[ni].heap_index.clear();
-
-        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
-          Node v = _graph.target(e);
-          int vb = _blossom_set->find(v);
-          int vi = (*_node_index)[v];
-
-          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
-            dualScale * _weight[e];
-
-          if ((*_blossom_data)[vb].status == EVEN) {
-            if (_delta3->state(e) != _delta3->IN_HEAP) {
-              _delta3->push(e, rw);
-            }
-          }
-        }
-      }
-    }
-
-    void unmatchedToMatched(int blossom) {
-      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
-           n != INVALID; ++n) {
-        int ni = (*_node_index)[n];
-
-        for (InArcIt e(_graph, n); e != INVALID; ++e) {
-          Node v = _graph.source(e);
-          int vb = _blossom_set->find(v);
-          int vi = (*_node_index)[v];
-
-          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
-            dualScale * _weight[e];
-
-          if (vb == blossom) {
-            if (_delta3->state(e) == _delta3->IN_HEAP) {
-              _delta3->erase(e);
-            }
-          } else if ((*_blossom_data)[vb].status == EVEN) {
-
-            if (_delta3->state(e) == _delta3->IN_HEAP) {
-              _delta3->erase(e);
-            }
-
-            int vt = _tree_set->find(vb);
-
-            Arc r = _graph.oppositeArc(e);
-
-            typename std::map<int, Arc>::iterator it =
-              (*_node_data)[ni].heap_index.find(vt);
-
-            if (it != (*_node_data)[ni].heap_index.end()) {
-              if ((*_node_data)[ni].heap[it->second] > rw) {
-                (*_node_data)[ni].heap.replace(it->second, r);
-                (*_node_data)[ni].heap.decrease(r, rw);
-                it->second = r;
-              }
-            } else {
-              (*_node_data)[ni].heap.push(r, rw);
-              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
-            }
-
-            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
-              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
-
-              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
-                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
-                             (*_blossom_data)[blossom].offset);
-              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
-                         (*_blossom_data)[blossom].offset){
-                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
-                                 (*_blossom_data)[blossom].offset);
-              }
-            }
-
-          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
-            if (_delta3->state(e) == _delta3->IN_HEAP) {
-              _delta3->erase(e);
-            }
-          }
-        }
-      }
-    }
-
     void alternatePath(int even, int tree) {
       int odd;
@@ -1295,9 +1208,7 @@
       destroyTree(tree);
 
-      (*_blossom_data)[blossom].status = UNMATCHED;
       (*_blossom_data)[blossom].base = node;
-      matchedToUnmatched(blossom);
-    }
-
+      (*_blossom_data)[blossom].next = INVALID;
+    }
 
     void augmentOnEdge(const Edge& edge) {
@@ -1306,24 +1217,29 @@
       int right = _blossom_set->find(_graph.v(edge));
 
-      if ((*_blossom_data)[left].status == EVEN) {
-        int left_tree = _tree_set->find(left);
-        alternatePath(left, left_tree);
-        destroyTree(left_tree);
-      } else {
-        (*_blossom_data)[left].status = MATCHED;
-        unmatchedToMatched(left);
-      }
-
-      if ((*_blossom_data)[right].status == EVEN) {
-        int right_tree = _tree_set->find(right);
-        alternatePath(right, right_tree);
-        destroyTree(right_tree);
-      } else {
-        (*_blossom_data)[right].status = MATCHED;
-        unmatchedToMatched(right);
-      }
+      int left_tree = _tree_set->find(left);
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
 
       (*_blossom_data)[left].next = _graph.direct(edge, true);
       (*_blossom_data)[right].next = _graph.direct(edge, false);
+    }
+
+    void augmentOnArc(const Arc& arc) {
+
+      int left = _blossom_set->find(_graph.source(arc));
+      int right = _blossom_set->find(_graph.target(arc));
+
+      (*_blossom_data)[left].status = MATCHED;
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = arc;
+      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
     }
 
@@ -1530,5 +1446,5 @@
           (*_blossom_data)[sb].pred = pred;
           (*_blossom_data)[sb].next =
-                           _graph.oppositeArc((*_blossom_data)[tb].next);
+            _graph.oppositeArc((*_blossom_data)[tb].next);
 
           pred = (*_blossom_data)[ub].next;
@@ -1630,5 +1546,5 @@
 
       for (int i = 0; i < int(blossoms.size()); ++i) {
-        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
+        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
 
           Value offset = (*_blossom_data)[blossoms[i]].offset;
@@ -1668,8 +1584,14 @@
         _delta4_index(0), _delta4(0),
 
-        _delta_sum() {}
+        _delta_sum(), _unmatched(0),
+
+        _fractional(0)
+    {}
 
     ~MaxWeightedMatching() {
       destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
     }
 
@@ -1686,4 +1608,7 @@
       createStructures();
 
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
       for (ArcIt e(_graph); e != INVALID; ++e) {
         (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
@@ -1699,4 +1624,13 @@
         (*_delta4_index)[i] = _delta4->PRE_HEAP;
       }
+
+      _unmatched = _node_num;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
 
       int index = 0;
@@ -1710,4 +1644,6 @@
         }
         (*_node_index)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
         (*_node_data)[index].pot = max;
         _delta1->push(n, max);
@@ -1734,9 +1670,159 @@
     }
 
+    /// \brief Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      _fractional->run();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        if (_fractional->matching(n) == INVALID) {
+          (*_blossom_data)[blossom].base = n;
+        }
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          _delta1->push(n, _fractional->nodeValue(n));
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            _delta1->push(v, _fractional->nodeValue(v));
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.target(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+
+            int vt = _tree_set->find(vb);
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[ni].heap_index.find(vt);
+
+            if (it != (*_node_data)[ni].heap_index.end()) {
+              if ((*_node_data)[ni].heap[it->second] > rw) {
+                (*_node_data)[ni].heap.replace(it->second, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
     /// \brief Start the algorithm
     ///
     /// This function starts the algorithm.
     ///
-    /// \pre \ref init() must be called before using this function.
+    /// \pre \ref init() or \ref fractionalInit() must be called
+    /// before using this function.
     void start() {
       enum OpType {
@@ -1744,6 +1830,5 @@
       };
 
-      int unmatched = _node_num;
-      while (unmatched > 0) {
+      while (_unmatched > 0) {
         Value d1 = !_delta1->empty() ?
           _delta1->prio() : std::numeric_limits<Value>::max();
@@ -1758,9 +1843,8 @@
           _delta4->prio() : std::numeric_limits<Value>::max();
 
-        _delta_sum = d1; OpType ot = D1;
+        _delta_sum = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
         if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
-        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
         if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
-
 
         switch (ot) {
@@ -1769,5 +1853,5 @@
             Node n = _delta1->top();
             unmatchNode(n);
-            --unmatched;
+            --_unmatched;
           }
           break;
@@ -1776,6 +1860,11 @@
             int blossom = _delta2->top();
             Node n = _blossom_set->classTop(blossom);
-            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
-            extendOnArc(e);
+            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
+            if ((*_blossom_data)[blossom].next == INVALID) {
+              augmentOnArc(a);
+              --_unmatched;
+            } else {
+              extendOnArc(a);
+            }
           }
           break;
@@ -1790,18 +1879,6 @@
               _delta3->pop();
             } else {
-              int left_tree;
-              if ((*_blossom_data)[left_blossom].status == EVEN) {
-                left_tree = _tree_set->find(left_blossom);
-              } else {
-                left_tree = -1;
-                ++unmatched;
-              }
-              int right_tree;
-              if ((*_blossom_data)[right_blossom].status == EVEN) {
-                right_tree = _tree_set->find(right_blossom);
-              } else {
-                right_tree = -1;
-                ++unmatched;
-              }
+              int left_tree = _tree_set->find(left_blossom);
+              int right_tree = _tree_set->find(right_blossom);
 
               if (left_tree == right_tree) {
@@ -1809,5 +1886,5 @@
               } else {
                 augmentOnEdge(e);
-                unmatched -= 2;
+                _unmatched -= 2;
               }
             }
@@ -1827,9 +1904,9 @@
     /// \note mwm.run() is just a shortcut of the following code.
     /// \code
-    ///   mwm.init();
+    ///   mwm.fractionalInit();
     ///   mwm.start();
     /// \endcode
     void run() {
-      init();
+      fractionalInit();
       start();
     }
@@ -1838,5 +1915,5 @@
 
     /// \name Primal Solution
-    /// Functions to get the primal solution, i.e. the maximum weighted 
+    /// Functions to get the primal solution, i.e. the maximum weighted
     /// matching.\n
     /// Either \ref run() or \ref start() function should be called before
@@ -1857,5 +1934,5 @@
         }
       }
-      return sum /= 2;
+      return sum / 2;
     }
 
@@ -1877,5 +1954,5 @@
     /// \brief Return \c true if the given edge is in the matching.
     ///
-    /// This function returns \c true if the given edge is in the found 
+    /// This function returns \c true if the given edge is in the found
     /// matching.
     ///
@@ -1888,5 +1965,5 @@
     ///
     /// This function returns the matching arc (or edge) incident to the
-    /// given node in the found matching or \c INVALID if the node is 
+    /// given node in the found matching or \c INVALID if the node is
     /// not covered by the matching.
     ///
@@ -1906,5 +1983,5 @@
     /// \brief Return the mate of the given node.
     ///
-    /// This function returns the mate of the given node in the found 
+    /// This function returns the mate of the given node in the found
     /// matching or \c INVALID if the node is not covered by the matching.
     ///
@@ -1926,6 +2003,6 @@
     /// \brief Return the value of the dual solution.
     ///
-    /// This function returns the value of the dual solution. 
-    /// It should be equal to the primal value scaled by \ref dualScale 
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
     /// "dual scale".
     ///
@@ -1982,7 +2059,7 @@
     /// \brief Iterator for obtaining the nodes of a blossom.
     ///
-    /// This class provides an iterator for obtaining the nodes of the 
+    /// This class provides an iterator for obtaining the nodes of the
     /// given blossom. It lists a subset of the nodes.
-    /// Before using this iterator, you must allocate a 
+    /// Before using this iterator, you must allocate a
     /// MaxWeightedMatching class and execute it.
     class BlossomIt {
@@ -1993,6 +2070,6 @@
       /// Constructor to get the nodes of the given variable.
       ///
-      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
-      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
+      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
+      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
       /// called before initializing this iterator.
       BlossomIt(const MaxWeightedMatching& algorithm, int variable)
@@ -2047,6 +2124,6 @@
   /// \f$O(nm\log n)\f$ time complexity.
   ///
-  /// The maximum weighted perfect matching problem is to find a subset of 
-  /// the edges in an undirected graph with maximum overall weight for which 
+  /// The maximum weighted perfect matching problem is to find a subset of
+  /// the edges in an undirected graph with maximum overall weight for which
   /// each node has exactly one incident edge.
   /// It can be formulated with the following linear program.
@@ -2071,14 +2148,14 @@
       \frac{\vert B \vert - 1}{2}z_B\f] */
   ///
-  /// The algorithm can be executed with the run() function. 
+  /// The algorithm can be executed with the run() function.
   /// After it the matching (the primal solution) and the dual solution
-  /// can be obtained using the query functions and the 
-  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
-  /// which is able to iterate on the nodes of a blossom. 
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
   /// If the value type is integer, then the dual solution is multiplied
   /// by \ref MaxWeightedMatching::dualScale "4".
   ///
   /// \tparam GR The undirected graph type the algorithm runs on.
-  /// \tparam WM The type edge weight map. The default type is 
+  /// \tparam WM The type edge weight map. The default type is
   /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 #ifdef DOXYGEN
@@ -2191,4 +2268,9 @@
 
     Value _delta_sum;
+    int _unmatched;
+
+    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
+    FractionalMatching;
+    FractionalMatching *_fractional;
 
     void createStructures() {
@@ -2199,10 +2281,15 @@
         _matching = new MatchingMap(_graph);
       }
+
       if (!_node_potential) {
         _node_potential = new NodePotential(_graph);
       }
+
       if (!_blossom_set) {
         _blossom_index = new IntNodeMap(_graph);
         _blossom_set = new BlossomSet(*_blossom_index);
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
         _blossom_data = new RangeMap<BlossomData>(_blossom_num);
       }
@@ -2213,4 +2300,8 @@
         _node_data = new RangeMap<NodeData>(_node_num,
                                             NodeData(*_node_heap_index));
+      } else if (_node_data->size() != _node_num) {
+        delete _node_data;
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
       }
 
@@ -2218,23 +2309,29 @@
         _tree_set_index = new IntIntMap(_blossom_num);
         _tree_set = new TreeSet(*_tree_set_index);
-      }
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
       if (!_delta2) {
         _delta2_index = new IntIntMap(_blossom_num);
         _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
-      }
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
       if (!_delta3) {
         _delta3_index = new IntEdgeMap(_graph);
         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
       }
+
       if (!_delta4) {
         _delta4_index = new IntIntMap(_blossom_num);
         _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      } else {
+        _delta4_index->resize(_blossom_num);
       }
     }
 
     void destroyStructures() {
-      _node_num = countNodes(_graph);
-      _blossom_num = _node_num * 3 / 2;
-
       if (_matching) {
         delete _matching;
@@ -2909,8 +3006,14 @@
         _delta4_index(0), _delta4(0),
 
-        _delta_sum() {}
+        _delta_sum(), _unmatched(0),
+
+        _fractional(0)
+    {}
 
     ~MaxWeightedPerfectMatching() {
       destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
     }
 
@@ -2927,4 +3030,7 @@
       createStructures();
 
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
       for (ArcIt e(_graph); e != INVALID; ++e) {
         (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
@@ -2937,4 +3043,12 @@
         (*_delta4_index)[i] = _delta4->PRE_HEAP;
       }
+
+      _unmatched = _node_num;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
 
       int index = 0;
@@ -2948,4 +3062,6 @@
         }
         (*_node_index)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
         (*_node_data)[index].pot = max;
         int blossom =
@@ -2971,9 +3087,153 @@
     }
 
+    /// \brief Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      if (!_fractional->run()) {
+        _unmatched = -1;
+        return;
+      }
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.target(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+
+            int vt = _tree_set->find(vb);
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[ni].heap_index.find(vt);
+
+            if (it != (*_node_data)[ni].heap_index.end()) {
+              if ((*_node_data)[ni].heap[it->second] > rw) {
+                (*_node_data)[ni].heap.replace(it->second, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
     /// \brief Start the algorithm
     ///
     /// This function starts the algorithm.
     ///
-    /// \pre \ref init() must be called before using this function.
+    /// \pre \ref init() or \ref fractionalInit() must be called before
+    /// using this function.
     bool start() {
       enum OpType {
@@ -2981,6 +3241,7 @@
       };
 
-      int unmatched = _node_num;
-      while (unmatched > 0) {
+      if (_unmatched == -1) return false;
+
+      while (_unmatched > 0) {
         Value d2 = !_delta2->empty() ?
           _delta2->prio() : std::numeric_limits<Value>::max();
@@ -2992,6 +3253,6 @@
           _delta4->prio() : std::numeric_limits<Value>::max();
 
-        _delta_sum = d2; OpType ot = D2;
-        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
+        _delta_sum = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
         if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
 
@@ -3026,5 +3287,5 @@
               } else {
                 augmentOnEdge(e);
-                unmatched -= 2;
+                _unmatched -= 2;
               }
             }
@@ -3045,9 +3306,9 @@
     /// \note mwpm.run() is just a shortcut of the following code.
     /// \code
-    ///   mwpm.init();
+    ///   mwpm.fractionalInit();
     ///   mwpm.start();
     /// \endcode
     bool run() {
-      init();
+      fractionalInit();
       return start();
     }
@@ -3056,5 +3317,5 @@
 
     /// \name Primal Solution
-    /// Functions to get the primal solution, i.e. the maximum weighted 
+    /// Functions to get the primal solution, i.e. the maximum weighted
     /// perfect matching.\n
     /// Either \ref run() or \ref start() function should be called before
@@ -3075,10 +3336,10 @@
         }
       }
-      return sum /= 2;
+      return sum / 2;
     }
 
     /// \brief Return \c true if the given edge is in the matching.
     ///
-    /// This function returns \c true if the given edge is in the found 
+    /// This function returns \c true if the given edge is in the found
     /// matching.
     ///
@@ -3091,5 +3352,5 @@
     ///
     /// This function returns the matching arc (or edge) incident to the
-    /// given node in the found matching or \c INVALID if the node is 
+    /// given node in the found matching or \c INVALID if the node is
     /// not covered by the matching.
     ///
@@ -3109,5 +3370,5 @@
     /// \brief Return the mate of the given node.
     ///
-    /// This function returns the mate of the given node in the found 
+    /// This function returns the mate of the given node in the found
     /// matching or \c INVALID if the node is not covered by the matching.
     ///
@@ -3128,6 +3389,6 @@
     /// \brief Return the value of the dual solution.
     ///
-    /// This function returns the value of the dual solution. 
-    /// It should be equal to the primal value scaled by \ref dualScale 
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
     /// "dual scale".
     ///
@@ -3184,7 +3445,7 @@
     /// \brief Iterator for obtaining the nodes of a blossom.
     ///
-    /// This class provides an iterator for obtaining the nodes of the 
+    /// This class provides an iterator for obtaining the nodes of the
     /// given blossom. It lists a subset of the nodes.
-    /// Before using this iterator, you must allocate a 
+    /// Before using this iterator, you must allocate a
     /// MaxWeightedPerfectMatching class and execute it.
     class BlossomIt {
@@ -3195,6 +3456,6 @@
       /// Constructor to get the nodes of the given variable.
       ///
-      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
-      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
+      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
+      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
       /// must be called before initializing this iterator.
       BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
@@ -3242,3 +3503,3 @@
 } //END OF NAMESPACE LEMON
 
-#endif //LEMON_MAX_MATCHING_H
+#endif //LEMON_MATCHING_H
Index: lemon/math.h
===================================================================
--- lemon/math.h	(revision 558)
+++ lemon/math.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -57,5 +57,5 @@
 
   ///Check whether the parameter is NaN or not
-  
+
   ///This function checks whether the parameter is NaN or not.
   ///Is should be equivalent with std::isnan(), but it is not
Index: lemon/min_cost_arborescence.h
===================================================================
--- lemon/min_cost_arborescence.h	(revision 891)
+++ lemon/min_cost_arborescence.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -129,6 +129,6 @@
   public:
 
-    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
-    /// of the algorithm. 
+    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
+    /// of the algorithm.
     typedef TR Traits;
     /// The type of the underlying digraph.
@@ -437,5 +437,5 @@
     /// \ref named-templ-param "Named parameter" for setting
     /// \c PredMap type.
-    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
     /// and its value type must be the \c Arc type of the digraph.
     template <class T>
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 898)
+++ lemon/network_simplex.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -98,5 +98,5 @@
       UNBOUNDED
     };
-    
+
     /// \brief Constants for selecting the type of the supply constraints.
     ///
@@ -116,5 +116,5 @@
       LEQ
     };
-    
+
     /// \brief Constants for selecting the pivot rule.
     ///
@@ -159,5 +159,5 @@
       ALTERING_LIST
     };
-    
+
   private:
 
@@ -165,14 +165,19 @@
 
     typedef std::vector<int> IntVector;
-    typedef std::vector<char> CharVector;
     typedef std::vector<Value> ValueVector;
     typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
 
     // State constants for arcs
-    enum ArcStateEnum {
+    enum ArcState {
       STATE_UPPER = -1,
       STATE_TREE  =  0,
       STATE_LOWER =  1
     };
+
+    typedef std::vector<signed char> StateVector;
+    // Note: vector<signed char> is used instead of vector<ArcState> for
+    // efficiency reasons
 
   private:
@@ -214,6 +219,6 @@
     IntVector _last_succ;
     IntVector _dirty_revs;
-    CharVector _forward;
-    CharVector _state;
+    BoolVector _forward;
+    StateVector _state;
     int _root;
 
@@ -223,9 +228,9 @@
     int stem, par_stem, new_stem;
     Value delta;
-    
+
     const Value MAX;
 
   public:
-  
+
     /// \brief Constant for infinite upper bounds (capacities).
     ///
@@ -246,5 +251,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const CharVector &_state;
+      const StateVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -267,5 +272,5 @@
       bool findEnteringArc() {
         Cost c;
-        for (int e = _next_arc; e < _search_arc_num; ++e) {
+        for (int e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -275,5 +280,5 @@
           }
         }
-        for (int e = 0; e < _next_arc; ++e) {
+        for (int e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -298,5 +303,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const CharVector &_state;
+      const StateVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -315,5 +320,5 @@
       bool findEnteringArc() {
         Cost c, min = 0;
-        for (int e = 0; e < _search_arc_num; ++e) {
+        for (int e = 0; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -337,5 +342,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const CharVector &_state;
+      const StateVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -356,5 +361,5 @@
       {
         // The main parameters of the pivot rule
-        const double BLOCK_SIZE_FACTOR = 0.5;
+        const double BLOCK_SIZE_FACTOR = 1.0;
         const int MIN_BLOCK_SIZE = 10;
 
@@ -369,5 +374,5 @@
         int cnt = _block_size;
         int e;
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -380,5 +385,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -410,5 +415,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const CharVector &_state;
+      const StateVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -471,5 +476,5 @@
         min = 0;
         _curr_length = 0;
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -482,5 +487,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -494,6 +499,6 @@
         }
         if (_curr_length == 0) return false;
-      
-      search_end:        
+
+      search_end:
         _minor_count = 1;
         _next_arc = e;
@@ -513,5 +518,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const CharVector &_state;
+      const StateVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -566,5 +571,5 @@
         // Check the current candidate list
         int e;
-        for (int i = 0; i < _curr_length; ++i) {
+        for (int i = 0; i != _curr_length; ++i) {
           e = _candidates[i];
           _cand_cost[e] = _state[e] *
@@ -579,5 +584,5 @@
         int limit = _head_length;
 
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           _cand_cost[e] = _state[e] *
             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
@@ -591,5 +596,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           _cand_cost[e] = _state[e] *
             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
@@ -604,5 +609,5 @@
         }
         if (_curr_length == 0) return false;
-        
+
       search_end:
 
@@ -630,5 +635,5 @@
     /// \param graph The digraph the algorithm runs on.
     /// \param arc_mixing Indicate if the arcs have to be stored in a
-    /// mixed order in the internal data structure. 
+    /// mixed order in the internal data structure.
     /// In special cases, it could lead to better overall performance,
     /// but it is usually slower. Therefore it is disabled by default.
@@ -645,5 +650,5 @@
       LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
         "The cost type of NetworkSimplex must be signed");
-        
+
       // Reset data structures
       reset();
@@ -759,5 +764,5 @@
       return *this;
     }
-    
+
     /// \brief Set the type of the supply constraints.
     ///
@@ -785,5 +790,5 @@
     /// This function runs the algorithm.
     /// The paramters can be specified using functions \ref lowerMap(),
-    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
     /// \ref supplyType().
     /// For example,
@@ -940,10 +945,10 @@
         }
       }
-      
+
       // Reset parameters
       resetParams();
       return *this;
     }
-    
+
     /// @}
 
@@ -1085,5 +1090,5 @@
         _state[i] = STATE_LOWER;
       }
-      
+
       // Set data for the artificial root node
       _root = _node_num;
@@ -1259,5 +1264,5 @@
       for (int u = second; u != join; u = _parent[u]) {
         e = _pred[u];
-        d = _forward[u] ? 
+        d = _forward[u] ?
           (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
         if (d <= delta) {
@@ -1361,5 +1366,5 @@
 
       // Update _rev_thread using the new _thread values
-      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
+      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
         u = _dirty_revs[i];
         _rev_thread[_thread[u]] = u;
@@ -1431,4 +1436,98 @@
         _pi[u] += sigma;
       }
+    }
+
+    // Heuristic initial pivots
+    bool initialPivots() {
+      Value curr, total = 0;
+      std::vector<Node> supply_nodes, demand_nodes;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        curr = _supply[_node_id[u]];
+        if (curr > 0) {
+          total += curr;
+          supply_nodes.push_back(u);
+        }
+        else if (curr < 0) {
+          demand_nodes.push_back(u);
+        }
+      }
+      if (_sum_supply > 0) total -= _sum_supply;
+      if (total <= 0) return true;
+
+      IntVector arc_vector;
+      if (_sum_supply >= 0) {
+        if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
+          // Perform a reverse graph search from the sink to the source
+          typename GR::template NodeMap<bool> reached(_graph, false);
+          Node s = supply_nodes[0], t = demand_nodes[0];
+          std::vector<Node> stack;
+          reached[t] = true;
+          stack.push_back(t);
+          while (!stack.empty()) {
+            Node u, v = stack.back();
+            stack.pop_back();
+            if (v == s) break;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              if (reached[u = _graph.source(a)]) continue;
+              int j = _arc_id[a];
+              if (_cap[j] >= total) {
+                arc_vector.push_back(j);
+                reached[u] = true;
+                stack.push_back(u);
+              }
+            }
+          }
+        } else {
+          // Find the min. cost incomming arc for each demand node
+          for (int i = 0; i != int(demand_nodes.size()); ++i) {
+            Node v = demand_nodes[i];
+            Cost c, min_cost = std::numeric_limits<Cost>::max();
+            Arc min_arc = INVALID;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              c = _cost[_arc_id[a]];
+              if (c < min_cost) {
+                min_cost = c;
+                min_arc = a;
+              }
+            }
+            if (min_arc != INVALID) {
+              arc_vector.push_back(_arc_id[min_arc]);
+            }
+          }
+        }
+      } else {
+        // Find the min. cost outgoing arc for each supply node
+        for (int i = 0; i != int(supply_nodes.size()); ++i) {
+          Node u = supply_nodes[i];
+          Cost c, min_cost = std::numeric_limits<Cost>::max();
+          Arc min_arc = INVALID;
+          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+            c = _cost[_arc_id[a]];
+            if (c < min_cost) {
+              min_cost = c;
+              min_arc = a;
+            }
+          }
+          if (min_arc != INVALID) {
+            arc_vector.push_back(_arc_id[min_arc]);
+          }
+        }
+      }
+
+      // Perform heuristic initial pivots
+      for (int i = 0; i != int(arc_vector.size()); ++i) {
+        in_arc = arc_vector[i];
+        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
+            _pi[_target[in_arc]]) >= 0) continue;
+        findJoinNode();
+        bool change = findLeavingArc();
+        if (delta >= MAX) return false;
+        changeFlow(change);
+        if (change) {
+          updateTreeStructure();
+          updatePotential();
+        }
+      }
+      return true;
     }
 
@@ -1455,4 +1554,7 @@
       PivotRuleImpl pivot(*this);
 
+      // Perform heuristic initial pivots
+      if (!initialPivots()) return UNBOUNDED;
+
       // Execute the Network Simplex algorithm
       while (pivot.findEnteringArc()) {
@@ -1466,5 +1568,5 @@
         }
       }
-      
+
       // Check feasibility
       for (int e = _search_arc_num; e != _all_arc_num; ++e) {
@@ -1483,5 +1585,5 @@
         }
       }
-      
+
       // Shift potentials to meet the requirements of the GEQ/LEQ type
       // optimality conditions
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 868)
+++ lemon/path.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -967,5 +967,5 @@
     };
 
-    
+
     template <typename From, typename To,
               bool revEnable = RevPathTagIndicator<From>::value>
@@ -973,5 +973,5 @@
       static void copy(const From& from, To& to) {
         PathCopySelectorForward<From, To>::copy(from, to);
-      }      
+      }
     };
 
@@ -980,5 +980,5 @@
       static void copy(const From& from, To& to) {
         PathCopySelectorBackward<From, To>::copy(from, to);
-      }      
+      }
     };
 
Index: lemon/planarity.h
===================================================================
--- lemon/planarity.h	(revision 896)
+++ lemon/planarity.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -141,5 +141,5 @@
     class PlanarityChecking {
     private:
-      
+
       TEMPLATE_GRAPH_TYPEDEFS(Graph);
 
@@ -147,9 +147,9 @@
 
     private:
-      
+
       typedef typename Graph::template NodeMap<Arc> PredMap;
-      
+
       typedef typename Graph::template EdgeMap<bool> TreeMap;
-      
+
       typedef typename Graph::template NodeMap<int> OrderMap;
       typedef std::vector<Node> OrderList;
@@ -222,5 +222,5 @@
 
           for (typename MergeRoots::Value::iterator it =
-                 merge_roots[node].begin(); 
+                 merge_roots[node].begin();
                it != merge_roots[node].end(); ++it) {
             int rn = *it;
@@ -433,5 +433,5 @@
 
               bool rd;
-              if (!external(xnode, rorder, child_lists, 
+              if (!external(xnode, rorder, child_lists,
                             ancestor_map, low_map)) {
                 rd = true;
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 891)
+++ lemon/preflow.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/quad_heap.h
===================================================================
--- lemon/quad_heap.h	(revision 929)
+++ lemon/quad_heap.h	(revision 929)
@@ -0,0 +1,343 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_QUAD_HEAP_H
+#define LEMON_QUAD_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Fourary (quaternary) heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Fourary (quaternary) heap data structure.
+  ///
+  /// This class implements the \e Fourary (\e quaternary) \e heap
+  /// data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
+  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
+  /// but its nodes have at most four children, instead of two.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa DHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class QuadHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    QuadHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    static int parent(int i) { return (i-1)/4; }
+    static int firstChild(int i) { return 4*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+3<length ) {
+          int min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx < 0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx = _iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first = j;
+    }
+
+  }; // class QuadHeap
+
+} // namespace lemon
+
+#endif // LEMON_FOURARY_HEAP_H
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 834)
+++ lemon/smart_graph.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -187,5 +187,5 @@
   ///\ref SmartDigraph is a simple and fast digraph implementation.
   ///It is also quite memory efficient but at the price
-  ///that it does not support node and arc deletion 
+  ///that it does not support node and arc deletion
   ///(except for the Snapshot feature).
   ///
@@ -336,5 +336,5 @@
     ///arcs from a SmartDigraph structure.
     ///
-    ///\note After a state is restored, you cannot restore a later state, 
+    ///\note After a state is restored, you cannot restore a later state,
     ///i.e. you cannot add the removed nodes and arcs again using
     ///another Snapshot instance.
@@ -615,5 +615,5 @@
   /// \ref SmartGraph is a simple and fast graph implementation.
   /// It is also quite memory efficient but at the price
-  /// that it does not support node and edge deletion 
+  /// that it does not support node and edge deletion
   /// (except for the Snapshot feature).
   ///
@@ -762,5 +762,5 @@
     ///edges from a SmartGraph structure.
     ///
-    ///\note After a state is restored, you cannot restore a later state, 
+    ///\note After a state is restored, you cannot restore a later state,
     ///i.e. you cannot add the removed nodes and edges again using
     ///another Snapshot instance.
Index: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 793)
+++ lemon/soplex.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -288,5 +288,5 @@
 
     _clear_temporals();
-    
+
     _applyMessageLevel();
 
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 793)
+++ lemon/soplex.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/static_graph.h
===================================================================
--- lemon/static_graph.h	(revision 834)
+++ lemon/static_graph.h	(revision 956)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,10 +32,10 @@
   public:
 
-    StaticDigraphBase() 
-      : built(false), node_num(0), arc_num(0), 
+    StaticDigraphBase()
+      : built(false), node_num(0), arc_num(0),
         node_first_out(NULL), node_first_in(NULL),
-        arc_source(NULL), arc_target(NULL), 
+        arc_source(NULL), arc_target(NULL),
         arc_next_in(NULL), arc_next_out(NULL) {}
-    
+
     ~StaticDigraphBase() {
       if (built) {
@@ -63,5 +63,5 @@
 
     class Arc {
-      friend class StaticDigraphBase;      
+      friend class StaticDigraphBase;
     protected:
       int id;
@@ -84,6 +84,6 @@
     static void next(Arc& e) { --e.id; }
 
-    void firstOut(Arc& e, const Node& n) const { 
-      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 
+    void firstOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
         node_first_out[n.id] : -1;
     }
@@ -114,9 +114,9 @@
       typedef typename Digraph::Arc Arc;
 
-      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 
+      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
         : digraph(_graph), nodeRef(_nodeRef) {}
-      
+
       bool operator()(const Arc& left, const Arc& right) const {
-	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
+        return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
       }
     private:
@@ -124,9 +124,9 @@
       const NodeRefMap& nodeRef;
     };
-    
+
   public:
 
     typedef True BuildTag;
-    
+
     void clear() {
       if (built) {
@@ -142,5 +142,5 @@
       arc_num = 0;
     }
-    
+
     template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
     void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
@@ -184,5 +184,5 @@
             int target = nodeRef[digraph.target(*it)].id;
             arcRef[*it] = Arc(arc_index);
-            arc_source[arc_index] = source; 
+            arc_source[arc_index] = source;
             arc_target[arc_index] = target;
             arc_next_in[arc_index] = node_first_in[target];
@@ -198,5 +198,5 @@
       node_first_out[node_num] = arc_num;
     }
-    
+
     template <typename ArcListIterator>
     void build(int n, ArcListIterator first, ArcListIterator last) {
@@ -213,9 +213,9 @@
       arc_next_out = new int[arc_num];
       arc_next_in = new int[arc_num];
-      
+
       for (int i = 0; i != node_num; ++i) {
         node_first_in[i] = -1;
-      }      
-      
+      }
+
       int arc_index = 0;
       for (int i = 0; i != node_num; ++i) {
@@ -283,5 +283,5 @@
   /// Since this digraph structure is completely static, its nodes and arcs
   /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
-  /// and <tt>[0..arcNum()-1]</tt>, respectively. 
+  /// and <tt>[0..arcNum()-1]</tt>, respectively.
   /// The index of an item is the same as its ID, it can be obtained
   /// using the corresponding \ref index() or \ref concepts::Digraph::id()
@@ -300,7 +300,7 @@
 
     typedef ExtendedStaticDigraphBase Parent;
-  
+
   public:
-  
+
     /// \brief Constructor
     ///
@@ -350,5 +350,5 @@
     /// This method also makes possible to copy a digraph to a StaticDigraph
     /// structure using \ref DigraphCopy.
-    /// 
+    ///
     /// \param digraph An existing digraph to be copied.
     /// \param nodeRef The node references will be copied into this map.
@@ -371,5 +371,5 @@
       Parent::build(digraph, nodeRef, arcRef);
     }
-  
+
     /// \brief Build the digraph from an arc list.
     ///
@@ -422,5 +422,5 @@
     using Parent::fastNextOut;
     using Parent::fastLastOut;
-    
+
   public:
 
@@ -433,6 +433,6 @@
 
       OutArcIt(const StaticDigraph& digraph, const Node& node) {
-	digraph.fastFirstOut(*this, node);
-	digraph.fastLastOut(last, node);
+        digraph.fastFirstOut(*this, node);
+        digraph.fastLastOut(last, node);
         if (last == *this) *this = INVALID;
       }
@@ -444,8 +444,8 @@
       }
 
-      OutArcIt& operator++() { 
+      OutArcIt& operator++() {
         StaticDigraph::fastNextOut(*this);
         if (last == *this) *this = INVALID;
-        return *this; 
+        return *this;
       }
 
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 670)
+++ lemon/suurballe.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,7 +30,51 @@
 #include <lemon/path.h>
 #include <lemon/list_graph.h>
+#include <lemon/dijkstra.h>
 #include <lemon/maps.h>
 
 namespace lemon {
+
+  /// \brief Default traits class of Suurballe algorithm.
+  ///
+  /// Default traits class of Suurballe algorithm.
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam LEN The type of the length map.
+  /// The default value is <tt>GR::ArcMap<int></tt>.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template < typename GR,
+             typename LEN = typename GR::template ArcMap<int> >
+#endif
+  struct SuurballeDefaultTraits
+  {
+    /// The type of the digraph.
+    typedef GR Digraph;
+    /// The type of the length map.
+    typedef LEN LengthMap;
+    /// The type of the lengths.
+    typedef typename LEN::Value Length;
+    /// The type of the flow map.
+    typedef typename GR::template ArcMap<int> FlowMap;
+    /// The type of the potential map.
+    typedef typename GR::template NodeMap<Length> PotentialMap;
+
+    /// \brief The path type
+    ///
+    /// The type used for storing the found arc-disjoint paths.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+
+    /// The cross reference type used for the heap.
+    typedef typename GR::template NodeMap<int> HeapCrossRef;
+
+    /// \brief The heap type used for internal Dijkstra computations.
+    ///
+    /// The type of the heap used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
+    /// and its priority type must be \c Length.
+    typedef BinHeap<Length, HeapCrossRef> Heap;
+  };
 
   /// \addtogroup shortest_path
@@ -47,5 +91,5 @@
   /// "minimum cost flow problem". This implementation is actually an
   /// efficient specialized version of the \ref CapacityScaling
-  /// "Successive Shortest Path" algorithm directly for this problem.
+  /// "successive shortest path" algorithm directly for this problem.
   /// Therefore this class provides query functions for flow values and
   /// node potentials (the dual solution) just like the minimum cost flow
@@ -56,13 +100,14 @@
   /// The default value is <tt>GR::ArcMap<int></tt>.
   ///
-  /// \warning Length values should be \e non-negative \e integers.
+  /// \warning Length values should be \e non-negative.
   ///
-  /// \note For finding node-disjoint paths this algorithm can be used
+  /// \note For finding \e node-disjoint paths, this algorithm can be used
   /// along with the \ref SplitNodes adaptor.
 #ifdef DOXYGEN
-  template <typename GR, typename LEN>
+  template <typename GR, typename LEN, typename TR>
 #else
   template < typename GR,
-             typename LEN = typename GR::template ArcMap<int> >
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = SuurballeDefaultTraits<GR, LEN> >
 #endif
   class Suurballe
@@ -75,24 +120,24 @@
   public:
 
-    /// The type of the digraph the algorithm runs on.
-    typedef GR Digraph;
+    /// The type of the digraph.
+    typedef typename TR::Digraph Digraph;
     /// The type of the length map.
-    typedef LEN LengthMap;
+    typedef typename TR::LengthMap LengthMap;
     /// The type of the lengths.
-    typedef typename LengthMap::Value Length;
-#ifdef DOXYGEN
+    typedef typename TR::Length Length;
+
     /// The type of the flow map.
-    typedef GR::ArcMap<int> FlowMap;
+    typedef typename TR::FlowMap FlowMap;
     /// The type of the potential map.
-    typedef GR::NodeMap<Length> PotentialMap;
-#else
-    /// The type of the flow map.
-    typedef typename Digraph::template ArcMap<int> FlowMap;
-    /// The type of the potential map.
-    typedef typename Digraph::template NodeMap<Length> PotentialMap;
-#endif
-
+    typedef typename TR::PotentialMap PotentialMap;
     /// The type of the path structures.
-    typedef SimplePath<GR> Path;
+    typedef typename TR::Path Path;
+    /// The cross reference type used for the heap.
+    typedef typename TR::HeapCrossRef HeapCrossRef;
+    /// The heap type used for internal Dijkstra computations.
+    typedef typename TR::Heap Heap;
+
+    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
 
   private:
@@ -105,42 +150,36 @@
     class ResidualDijkstra
     {
-      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
-      typedef BinHeap<Length, HeapCrossRef> Heap;
-
     private:
 
-      // The digraph the algorithm runs on
       const Digraph &_graph;
-
-      // The main maps
+      const LengthMap &_length;
       const FlowMap &_flow;
-      const LengthMap &_length;
-      PotentialMap &_potential;
-
-      // The distance map
-      PotentialMap _dist;
-      // The pred arc map
+      PotentialMap &_pi;
       PredMap &_pred;
-      // The processed (i.e. permanently labeled) nodes
-      std::vector<Node> _proc_nodes;
-
       Node _s;
       Node _t;
 
+      PotentialMap _dist;
+      std::vector<Node> _proc_nodes;
+
     public:
 
-      /// Constructor.
-      ResidualDijkstra( const Digraph &graph,
-                        const FlowMap &flow,
-                        const LengthMap &length,
-                        PotentialMap &potential,
-                        PredMap &pred,
-                        Node s, Node t ) :
-        _graph(graph), _flow(flow), _length(length), _potential(potential),
-        _dist(graph), _pred(pred), _s(s), _t(t) {}
-
-      /// \brief Run the algorithm. It returns \c true if a path is found
-      /// from the source node to the target node.
-      bool run() {
+      // Constructor
+      ResidualDijkstra(Suurballe &srb) :
+        _graph(srb._graph), _length(srb._length),
+        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
+        _s(srb._s), _t(srb._t), _dist(_graph) {}
+
+      // Run the algorithm and return true if a path is found
+      // from the source node to the target node.
+      bool run(int cnt) {
+        return cnt == 0 ? startFirst() : start();
+      }
+
+    private:
+
+      // Execute the algorithm for the first time (the flow and potential
+      // functions have to be identically zero).
+      bool startFirst() {
         HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
         Heap heap(heap_cross_ref);
@@ -152,8 +191,53 @@
         while (!heap.empty() && heap.top() != _t) {
           Node u = heap.top(), v;
-          Length d = heap.prio() + _potential[u], nd;
+          Length d = heap.prio(), dn;
           _dist[u] = heap.prio();
+          _proc_nodes.push_back(u);
           heap.pop();
+
+          // Traverse outgoing arcs
+          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
+            v = _graph.target(e);
+            switch(heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d + _length[e]);
+                _pred[v] = e;
+                break;
+              case Heap::IN_HEAP:
+                dn = d + _length[e];
+                if (dn < heap[v]) {
+                  heap.decrease(v, dn);
+                  _pred[v] = e;
+                }
+                break;
+              case Heap::POST_HEAP:
+                break;
+            }
+          }
+        }
+        if (heap.empty()) return false;
+
+        // Update potentials of processed nodes
+        Length t_dist = heap.prio();
+        for (int i = 0; i < int(_proc_nodes.size()); ++i)
+          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
+        return true;
+      }
+
+      // Execute the algorithm.
+      bool start() {
+        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
+        Heap heap(heap_cross_ref);
+        heap.push(_s, 0);
+        _pred[_s] = INVALID;
+        _proc_nodes.clear();
+
+        // Process nodes
+        while (!heap.empty() && heap.top() != _t) {
+          Node u = heap.top(), v;
+          Length d = heap.prio() + _pi[u], dn;
+          _dist[u] = heap.prio();
           _proc_nodes.push_back(u);
+          heap.pop();
 
           // Traverse outgoing arcs
@@ -162,17 +246,17 @@
               v = _graph.target(e);
               switch(heap.state(v)) {
-              case Heap::PRE_HEAP:
-                heap.push(v, d + _length[e] - _potential[v]);
-                _pred[v] = e;
-                break;
-              case Heap::IN_HEAP:
-                nd = d + _length[e] - _potential[v];
-                if (nd < heap[v]) {
-                  heap.decrease(v, nd);
+                case Heap::PRE_HEAP:
+                  heap.push(v, d + _length[e] - _pi[v]);
                   _pred[v] = e;
-                }
-                break;
-              case Heap::POST_HEAP:
-                break;
+                  break;
+                case Heap::IN_HEAP:
+                  dn = d + _length[e] - _pi[v];
+                  if (dn < heap[v]) {
+                    heap.decrease(v, dn);
+                    _pred[v] = e;
+                  }
+                  break;
+                case Heap::POST_HEAP:
+                  break;
               }
             }
@@ -184,17 +268,17 @@
               v = _graph.source(e);
               switch(heap.state(v)) {
-              case Heap::PRE_HEAP:
-                heap.push(v, d - _length[e] - _potential[v]);
-                _pred[v] = e;
-                break;
-              case Heap::IN_HEAP:
-                nd = d - _length[e] - _potential[v];
-                if (nd < heap[v]) {
-                  heap.decrease(v, nd);
+                case Heap::PRE_HEAP:
+                  heap.push(v, d - _length[e] - _pi[v]);
                   _pred[v] = e;
-                }
-                break;
-              case Heap::POST_HEAP:
-                break;
+                  break;
+                case Heap::IN_HEAP:
+                  dn = d - _length[e] - _pi[v];
+                  if (dn < heap[v]) {
+                    heap.decrease(v, dn);
+                    _pred[v] = e;
+                  }
+                  break;
+                case Heap::POST_HEAP:
+                  break;
               }
             }
@@ -206,9 +290,86 @@
         Length t_dist = heap.prio();
         for (int i = 0; i < int(_proc_nodes.size()); ++i)
-          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
+          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
         return true;
       }
 
     }; //class ResidualDijkstra
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    template <typename T>
+    struct SetFlowMap
+      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPotentialMapTraits : public Traits {
+      typedef T PotentialMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    template <typename T>
+    struct SetPotentialMap
+      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public Suurballe<GR, LEN, SetPathTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
+    };
+
+    template <typename H, typename CR>
+    struct SetHeapTraits : public Traits {
+      typedef H Heap;
+      typedef CR HeapCrossRef;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c Heap and \c HeapCrossRef types.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c Heap
+    /// and \c HeapCrossRef types with automatic allocation.
+    /// They will be used for internal Dijkstra computations.
+    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
+    /// concept and its priority type must be \c Length.
+    template <typename H,
+              typename CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
+      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
+    };
+
+    /// @}
 
   private:
@@ -227,17 +388,23 @@
 
     // The source node
-    Node _source;
+    Node _s;
     // The target node
-    Node _target;
+    Node _t;
 
     // Container to store the found paths
-    std::vector< SimplePath<Digraph> > paths;
+    std::vector<Path> _paths;
     int _path_num;
 
     // The pred arc map
     PredMap _pred;
-    // Implementation of the Dijkstra algorithm for finding augmenting
-    // shortest paths in the residual network
-    ResidualDijkstra *_dijkstra;
+
+    // Data for full init
+    PotentialMap *_init_dist;
+    PredMap *_init_pred;
+    bool _full_init;
+
+  protected:
+
+    Suurballe() {}
 
   public:
@@ -252,9 +419,7 @@
                const LengthMap &length ) :
       _graph(graph), _length(length), _flow(0), _local_flow(false),
-      _potential(0), _local_potential(false), _pred(graph)
-    {
-      LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
-        "The length type of Suurballe must be integer");
-    }
+      _potential(0), _local_potential(false), _pred(graph),
+      _init_dist(0), _init_pred(0)
+    {}
 
     /// Destructor.
@@ -262,5 +427,6 @@
       if (_local_flow) delete _flow;
       if (_local_potential) delete _potential;
-      delete _dijkstra;
+      delete _init_dist;
+      delete _init_pred;
     }
 
@@ -307,8 +473,11 @@
     /// \name Execution Control
     /// The simplest way to execute the algorithm is to call the run()
-    /// function.
-    /// \n
+    /// function.\n
+    /// If you need to execute the algorithm many times using the same
+    /// source node, then you may call fullInit() once and start()
+    /// for each target node.\n
     /// If you only need the flow that is the union of the found
-    /// arc-disjoint paths, you may call init() and findFlow().
+    /// arc-disjoint paths, then you may call findFlow() instead of
+    /// start().
 
     /// @{
@@ -330,11 +499,9 @@
     /// \code
     ///   s.init(s);
-    ///   s.findFlow(t, k);
-    ///   s.findPaths();
+    ///   s.start(t, k);
     /// \endcode
     int run(const Node& s, const Node& t, int k = 2) {
       init(s);
-      findFlow(t, k);
-      findPaths();
+      start(t, k);
       return _path_num;
     }
@@ -342,9 +509,9 @@
     /// \brief Initialize the algorithm.
     ///
-    /// This function initializes the algorithm.
+    /// This function initializes the algorithm with the given source node.
     ///
     /// \param s The source node.
     void init(const Node& s) {
-      _source = s;
+      _s = s;
 
       // Initialize maps
@@ -357,6 +524,61 @@
         _local_potential = true;
       }
-      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
-      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
+      _full_init = false;
+    }
+
+    /// \brief Initialize the algorithm and perform Dijkstra.
+    ///
+    /// This function initializes the algorithm and performs a full
+    /// Dijkstra search from the given source node. It makes consecutive
+    /// executions of \ref start() "start(t, k)" faster, since they
+    /// have to perform %Dijkstra only k-1 times.
+    ///
+    /// This initialization is usually worth using instead of \ref init()
+    /// if the algorithm is executed many times using the same source node.
+    ///
+    /// \param s The source node.
+    void fullInit(const Node& s) {
+      // Initialize maps
+      init(s);
+      if (!_init_dist) {
+        _init_dist = new PotentialMap(_graph);
+      }
+      if (!_init_pred) {
+        _init_pred = new PredMap(_graph);
+      }
+
+      // Run a full Dijkstra
+      typename Dijkstra<Digraph, LengthMap>
+        ::template SetStandardHeap<Heap>
+        ::template SetDistMap<PotentialMap>
+        ::template SetPredMap<PredMap>
+        ::Create dijk(_graph, _length);
+      dijk.distMap(*_init_dist).predMap(*_init_pred);
+      dijk.run(s);
+
+      _full_init = true;
+    }
+
+    /// \brief Execute the algorithm.
+    ///
+    /// This function executes the algorithm.
+    ///
+    /// \param t The target node.
+    /// \param k The number of paths to be found.
+    ///
+    /// \return \c k if there are at least \c k arc-disjoint paths from
+    /// \c s to \c t in the digraph. Otherwise it returns the number of
+    /// arc-disjoint paths found.
+    ///
+    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
+    /// just a shortcut of the following code.
+    /// \code
+    ///   s.findFlow(t, k);
+    ///   s.findPaths();
+    /// \endcode
+    int start(const Node& t, int k = 2) {
+      findFlow(t, k);
+      findPaths();
+      return _path_num;
     }
 
@@ -376,18 +598,37 @@
     /// \pre \ref init() must be called before using this function.
     int findFlow(const Node& t, int k = 2) {
-      _target = t;
-      _dijkstra =
-        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
-                              _source, _target );
+      _t = t;
+      ResidualDijkstra dijkstra(*this);
+
+      // Initialization
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_flow)[e] = 0;
+      }
+      if (_full_init) {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = (*_init_dist)[n];
+        }
+        Node u = _t;
+        Arc e;
+        while ((e = (*_init_pred)[u]) != INVALID) {
+          (*_flow)[e] = 1;
+          u = _graph.source(e);
+        }
+        _path_num = 1;
+      } else {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = 0;
+        }
+        _path_num = 0;
+      }
 
       // Find shortest paths
-      _path_num = 0;
       while (_path_num < k) {
         // Run Dijkstra
-        if (!_dijkstra->run()) break;
+        if (!dijkstra.run(_path_num)) break;
         ++_path_num;
 
         // Set the flow along the found shortest path
-        Node u = _target;
+        Node u = _t;
         Arc e;
         while ((e = _pred[u]) != INVALID) {
@@ -406,6 +647,6 @@
     /// \brief Compute the paths from the flow.
     ///
-    /// This function computes the paths from the found minimum cost flow,
-    /// which is the union of some arc-disjoint paths.
+    /// This function computes arc-disjoint paths from the found minimum
+    /// cost flow, which is the union of them.
     ///
     /// \pre \ref init() and \ref findFlow() must be called before using
@@ -415,13 +656,13 @@
       for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
 
-      paths.clear();
-      paths.resize(_path_num);
+      _paths.clear();
+      _paths.resize(_path_num);
       for (int i = 0; i < _path_num; ++i) {
-        Node n = _source;
-        while (n != _target) {
+        Node n = _s;
+        while (n != _t) {
           OutArcIt e(_graph, n);
           for ( ; res_flow[e] == 0; ++e) ;
           n = _graph.target(e);
-          paths[i].addBack(e);
+          _paths[i].addBack(e);
           res_flow[e] = 0;
         }
@@ -521,6 +762,6 @@
     /// \pre \ref run() or \ref findPaths() must be called before using
     /// this function.
-    Path path(int i) const {
-      return paths[i];
+    const Path& path(int i) const {
+      return _paths[i];
     }
 
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 864)
+++ lemon/unionfind.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1289,4 +1289,13 @@
         first_free_class(-1), first_free_node(-1) {}
 
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      nodes.clear();
+      classes.clear();
+      first_free_node = first_free_class = first_class = -1;
+    }
+
     /// \brief Insert a new node into a new component.
     ///
Index: scripts/bootstrap.sh
===================================================================
--- scripts/bootstrap.sh	(revision 841)
+++ scripts/bootstrap.sh	(revision 923)
@@ -44,4 +44,7 @@
 augment_config LEMON_INSTALL_PREFIX /usr/local \
     "# LEMON installation prefix"
+
+augment_config GLPK_PREFIX /usr/local/ \
+    "# GLPK installation root prefix"
 
 augment_config COIN_OR_PREFIX /usr/local/coin-or \
@@ -110,4 +113,15 @@
 fi
 
+if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
+    if yesorno "Use GLPK" "y"
+    then
+        glpk_flag="--with-glpk=$GLPK_PREFIX"
+    else
+        glpk_flag="--without-glpk"
+    fi
+else
+    glpk_flag="--without-glpk"        
+fi
+
 if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
     if yesorno "Use COIN-OR (CBC/CLP)" "n"
@@ -115,8 +129,8 @@
         coin_flag="--with-coin=$COIN_OR_PREFIX"
     else
-        coin_flag=""
+        coin_flag="--without-coin"
     fi
 else
-    coin_flag=""        
+    coin_flag="--without-coin"        
 fi
 
@@ -126,8 +140,8 @@
         soplex_flag="--with-soplex=$SOPLEX_PREFIX"
     else
-        soplex_flag=""
+        soplex_flag="--without-soplex"
     fi
 else
-    soplex_flag=""
+    soplex_flag="--without-soplex"
 fi
 
@@ -138,4 +152,5 @@
 $valgrind_flags \
 "$cxx_flags" \
+$glpk_flag \
 $coin_flag \
 $soplex_flag \
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 863)
+++ test/CMakeLists.txt	(revision 953)
@@ -22,4 +22,5 @@
   error_test
   euler_test
+  fractional_matching_test
   gomory_hu_test
   graph_copy_test
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 863)
+++ test/Makefile.am	(revision 953)
@@ -24,4 +24,5 @@
 	test/error_test \
 	test/euler_test \
+	test/fractional_matching_test \
 	test/gomory_hu_test \
 	test/graph_copy_test \
@@ -72,4 +73,5 @@
 test_error_test_SOURCES = test/error_test.cc
 test_euler_test_SOURCES = test/euler_test.cc
+test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
 test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 958)
+++ test/bellman_ford_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -98,5 +98,5 @@
     pp = const_bf_test.path(t);
     pp = const_bf_test.negativeCycle();
-    
+
     for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
   }
@@ -105,4 +105,5 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
       ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
+      ::SetOperationTraits<BellmanFordToleranceOperationTraits<Value, 0> >
       ::Create bf_test(gr,length);
 
@@ -110,5 +111,5 @@
     concepts::ReadWriteMap<Node,Arc> pred_map;
     concepts::ReadWriteMap<Node,Value> dist_map;
-    
+
     bf_test
       .lengthMap(length_map)
@@ -189,5 +190,5 @@
   check(pathSource(gr, p) == s, "path() found a wrong path.");
   check(pathTarget(gr, p) == t, "path() found a wrong path.");
-  
+
   ListPath<Digraph> path;
   Value dist;
@@ -228,16 +229,16 @@
   SmartDigraph gr;
   IntArcMap length(gr);
-  
+
   Node n1 = gr.addNode();
   Node n2 = gr.addNode();
   Node n3 = gr.addNode();
   Node n4 = gr.addNode();
-  
+
   Arc a1 = gr.addArc(n1, n2);
   Arc a2 = gr.addArc(n2, n2);
-  
+
   length[a1] = 2;
   length[a2] = -1;
-  
+
   {
     BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
@@ -247,7 +248,7 @@
           "Wrong negative cycle.");
   }
- 
+
   length[a2] = 0;
-  
+
   {
     BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
@@ -256,10 +257,10 @@
           "Negative cycle should not be found.");
   }
-  
+
   length[gr.addArc(n1, n3)] = 5;
   length[gr.addArc(n4, n3)] = 1;
   length[gr.addArc(n2, n4)] = 2;
   length[gr.addArc(n3, n2)] = -4;
-  
+
   {
     BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 632)
+++ test/bfs_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -84,5 +84,5 @@
     b = const_bfs_test.emptyQueue();
     i = const_bfs_test.queueSize();
-    
+
     bfs_test.start();
     bfs_test.start(t);
@@ -105,10 +105,10 @@
       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
       ::Create bfs_test(G);
-      
+
     concepts::ReadWriteMap<Node,Arc> pred_map;
     concepts::ReadWriteMap<Node,int> dist_map;
     concepts::ReadWriteMap<Node,bool> reached_map;
     concepts::WriteMap<Node,bool> processed_map;
-    
+
     bfs_test
       .predMap(pred_map)
@@ -120,5 +120,5 @@
     bfs_test.run(s,t);
     bfs_test.run();
-    
+
     bfs_test.init();
     bfs_test.addSource(s);
@@ -129,5 +129,5 @@
     b = bfs_test.emptyQueue();
     i = bfs_test.queueSize();
-    
+
     bfs_test.start();
     bfs_test.start(t);
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 736)
+++ test/circulation_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -82,5 +82,5 @@
   CirculationType circ_test(g, lcap, ucap, supply);
   const CirculationType& const_circ_test = circ_test;
-   
+
   circ_test
     .lowerMap(lcap)
@@ -88,5 +88,5 @@
     .supplyMap(supply)
     .flowMap(flow);
-  
+
   const CirculationType::Elevator& elev = const_circ_test.elevator();
   circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
@@ -103,5 +103,5 @@
   b = const_circ_test.barrier(n);
   const_circ_test.barrierMap(bar);
-  
+
   ignore_unused_variable_warning(fm);
 }
Index: test/connectivity_test.cc
===================================================================
--- test/connectivity_test.cc	(revision 696)
+++ test/connectivity_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,10 +30,10 @@
   typedef ListDigraph Digraph;
   typedef Undirector<Digraph> Graph;
-  
-  {
-    Digraph d;
-    Digraph::NodeMap<int> order(d);
-    Graph g(d);
-    
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
     check(stronglyConnected(d), "The empty digraph is strongly connected");
     check(countStronglyConnectedComponents(d) == 0,
@@ -49,5 +49,5 @@
     check(countBiEdgeConnectedComponents(g) == 0,
           "The empty graph has 0 bi-edge-connected component");
-          
+
     check(dag(d), "The empty digraph is DAG.");
     check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
@@ -83,5 +83,5 @@
     check(countBiEdgeConnectedComponents(g) == 1,
           "This graph has 1 bi-edge-connected component");
-          
+
     check(dag(d), "This digraph is DAG.");
     check(checkedTopologicalSort(d, order), "This digraph is DAG.");
@@ -102,5 +102,5 @@
     Digraph::NodeMap<int> order(d);
     Graph g(d);
-    
+
     Digraph::Node n1 = d.addNode();
     Digraph::Node n2 = d.addNode();
@@ -109,5 +109,5 @@
     Digraph::Node n5 = d.addNode();
     Digraph::Node n6 = d.addNode();
-    
+
     d.addArc(n1, n3);
     d.addArc(n3, n2);
@@ -137,21 +137,21 @@
     check(!parallelFree(g), "This graph is not parallel-free.");
     check(!simpleGraph(g), "This graph is not simple.");
-    
+
     d.addArc(n3, n3);
-    
+
     check(!loopFree(d), "This digraph is not loop-free.");
     check(!loopFree(g), "This graph is not loop-free.");
     check(!simpleGraph(d), "This digraph is not simple.");
-    
+
     d.addArc(n3, n2);
-    
+
     check(!parallelFree(d), "This digraph is not parallel-free.");
   }
-  
+
   {
     Digraph d;
     Digraph::ArcMap<bool> cutarcs(d, false);
     Graph g(d);
-    
+
     Digraph::Node n1 = d.addNode();
     Digraph::Node n2 = d.addNode();
@@ -173,5 +173,5 @@
     d.addArc(n6, n7);
     d.addArc(n7, n6);
-   
+
     check(!stronglyConnected(d), "This digraph is not strongly connected");
     check(countStronglyConnectedComponents(d) == 3,
@@ -236,5 +236,5 @@
     Digraph d;
     Digraph::NodeMap<int> order(d);
-    
+
     Digraph::Node belt = d.addNode();
     Digraph::Node trousers = d.addNode();
@@ -256,5 +256,5 @@
     d.addArc(shirt, necktie);
     d.addArc(necktie, coat);
-    
+
     check(dag(d), "This digraph is DAG.");
     topologicalSort(d, order);
@@ -268,5 +268,5 @@
     ListGraph g;
     ListGraph::NodeMap<bool> map(g);
-    
+
     ListGraph::Node n1 = g.addNode();
     ListGraph::Node n2 = g.addNode();
@@ -284,8 +284,8 @@
     g.addEdge(n4, n7);
     g.addEdge(n5, n7);
-   
+
     check(bipartite(g), "This graph is bipartite");
     check(bipartitePartitions(g, map), "This graph is bipartite");
-    
+
     check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
           "Wrong bipartitePartitions()");
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 632)
+++ test/dfs_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -84,5 +84,5 @@
     b = const_dfs_test.emptyQueue();
     i = const_dfs_test.queueSize();
-    
+
     dfs_test.start();
     dfs_test.start(t);
@@ -110,5 +110,5 @@
     concepts::ReadWriteMap<Node,bool> reached_map;
     concepts::WriteMap<Node,bool> processed_map;
-    
+
     dfs_test
       .predMap(pred_map)
@@ -127,5 +127,5 @@
     b = dfs_test.emptyQueue();
     i = dfs_test.queueSize();
-    
+
     dfs_test.start();
     dfs_test.start(t);
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 827)
+++ test/digraph_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -393,7 +393,7 @@
   SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
   SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
-  
+
   StaticDigraph G;
-  
+
   checkGraphNodeList(G, 0);
   checkGraphArcList(G, 0);
@@ -465,5 +465,5 @@
 
   G.build(6, arcs.begin(), arcs.end());
-  
+
   checkGraphNodeList(G, 6);
   checkGraphArcList(G, 9);
@@ -489,5 +489,5 @@
   checkGraphNodeMap(G);
   checkGraphArcMap(G);
-  
+
   int n = G.nodeNum();
   int m = G.arcNum();
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 632)
+++ test/dijkstra_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -86,5 +86,5 @@
     b = const_dijkstra_test.emptyQueue();
     i = const_dijkstra_test.queueSize();
-    
+
     dijkstra_test.start();
     dijkstra_test.start(t);
@@ -110,5 +110,5 @@
       ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
       ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
-      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
                 concepts::ReadWriteMap<Node,int> >
       ::Create dijkstra_test(G,length);
@@ -120,5 +120,5 @@
     concepts::ReadWriteMap<Node,int> heap_cross_ref;
     BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
-    
+
     dijkstra_test
       .lengthMap(length_map)
@@ -137,5 +137,5 @@
     b = dijkstra_test.emptyQueue();
     i = dijkstra_test.queueSize();
-    
+
     dijkstra_test.start();
     dijkstra_test.start(t);
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 559)
+++ test/edge_set_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 639)
+++ test/euler_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -86,9 +86,9 @@
   typedef ListDigraph Digraph;
   typedef Undirector<Digraph> Graph;
-  
-  {
-    Digraph d;
-    Graph g(d);
-    
+
+  {
+    Digraph d;
+    Graph g(d);
+
     checkDiEulerIt(d);
     checkDiEulerIt(g);
@@ -129,5 +129,5 @@
     Digraph::Node n2 = d.addNode();
     Digraph::Node n3 = d.addNode();
-    
+
     d.addArc(n1, n2);
     d.addArc(n2, n1);
@@ -154,5 +154,5 @@
     Digraph::Node n5 = d.addNode();
     Digraph::Node n6 = d.addNode();
-    
+
     d.addArc(n1, n2);
     d.addArc(n2, n4);
@@ -190,5 +190,5 @@
     Digraph::Node n4 = d.addNode();
     Digraph::Node n5 = d.addNode();
-    
+
     d.addArc(n1, n2);
     d.addArc(n2, n3);
@@ -212,5 +212,5 @@
     Digraph::Node n2 = d.addNode();
     Digraph::Node n3 = d.addNode();
-    
+
     d.addArc(n1, n2);
     d.addArc(n2, n3);
Index: test/fractional_matching_test.cc
===================================================================
--- test/fractional_matching_test.cc	(revision 956)
+++ test/fractional_matching_test.cc	(revision 956)
@@ -0,0 +1,525 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <cstdlib>
+
+#include <lemon/fractional_matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 4;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "7 4  0      984\n"
+  "0 7  1      73\n"
+  "7 1  2      204\n"
+  "2 3  3      583\n"
+  "2 7  4      565\n"
+  "2 1  5      582\n"
+  "0 4  6      551\n"
+  "2 5  7      385\n"
+  "1 5  8      561\n"
+  "5 3  9      484\n"
+  "7 5  10     904\n"
+  "3 6  11     47\n"
+  "7 6  12     888\n"
+  "3 0  13     747\n"
+  "6 1  14     310\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "2 5  0      710\n"
+  "0 5  1      241\n"
+  "2 4  2      856\n"
+  "2 6  3      762\n"
+  "4 1  4      747\n"
+  "6 1  5      962\n"
+  "4 7  6      723\n"
+  "1 7  7      661\n"
+  "2 3  8      376\n"
+  "1 0  9      416\n"
+  "6 7  10     391\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "6 2  0      553\n"
+  "0 7  1      653\n"
+  "6 3  2      22\n"
+  "4 7  3      846\n"
+  "7 2  4      981\n"
+  "7 6  5      250\n"
+  "5 2  6      539\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "@edges\n"
+  "     label  weight\n"
+  "0 0  0      100\n"
+};
+
+void checkMaxFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+
+  Graph g;
+  Node n;
+  Edge e;
+
+  MaxFractionalMatching<Graph> mat_test(g);
+  const MaxFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.start(true);
+  mat_test.startPerfect();
+  mat_test.startPerfect(true);
+  mat_test.run();
+  mat_test.run(true);
+  mat_test.runPerfect();
+  mat_test.runPerfect(true);
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkMaxWeightedPerfectFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool allow_loops = true) {
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    if (mfm.matching(n) != INVALID) {
+      check(indeg == 1, "Invalid matching");
+      ++pv;
+    } else {
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+  check(pv == mfm.matchingSize(), "Wrong matching size");
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+          mfm.matching(e), "Invalid matching");
+  }
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  int anum = 0, bnum = 0;
+  SmartGraph::NodeMap<bool> neighbours(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (!mfm.barrier(n)) continue;
+    ++anum;
+    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+      Node u = graph.source(a);
+      if (!allow_loops && u == n) continue;
+      if (!neighbours[u]) {
+        neighbours[u] = true;
+        ++bnum;
+      }
+    }
+  }
+  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
+        "Wrong barrier");
+}
+
+void checkPerfectFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool perfect, bool allow_loops = true) {
+  if (perfect) {
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      int indeg = 0;
+      for (InArcIt a(graph, n); a != INVALID; ++a) {
+        if (mfm.matching(graph.source(a)) == a) {
+          ++indeg;
+        }
+      }
+      check(mfm.matching(n) != INVALID, "Invalid matching");
+      check(indeg == 1, "Invalid matching");
+    }
+    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+            (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+            mfm.matching(e), "Invalid matching");
+    }
+  } else {
+    int anum = 0, bnum = 0;
+    SmartGraph::NodeMap<bool> neighbours(graph, false);
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      if (!mfm.barrier(n)) continue;
+      ++anum;
+      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+        Node u = graph.source(a);
+        if (!allow_loops && u == n) continue;
+        if (!neighbours[u]) {
+          neighbours[u] = true;
+          ++bnum;
+        }
+      }
+    }
+    check(anum - bnum > 0, "Wrong barrier");
+  }
+}
+
+void checkWeightedFractionalMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
+                   bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
+      - weight[e] * mwfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(indeg <= 1, "Invalid matching");
+    if (mwfm.matching(n) != INVALID) {
+      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
+      check(indeg == 1, "Invalid matching");
+      pv += weight[mwfm.matching(n)];
+      SmartGraph::Node o = graph.target(mwfm.matching(n));
+    } else {
+      check(mwfm.nodeValue(n) == 0, "Invalid matching");
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwfm.nodeValue(n);
+  }
+
+  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  return;
+}
+
+void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
+                const SmartGraph::EdgeMap<int>& weight,
+                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
+                bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
+      - weight[e] * mwpfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwpfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
+    check(indeg == 1, "Invalid perfect matching");
+    pv += weight[mwpfm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpfm.matching(n));
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwpfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpfm.nodeValue(n);
+  }
+
+  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwpfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwpfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwpfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartGraph graph;
+    SmartGraph::EdgeMap<int> weight(graph);
+
+    istringstream lgfs(lgf[i]);
+    graphReader(graph, lgfs).
+      edgeMap("weight", weight).run();
+
+    bool perfect_with_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, true);
+      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    bool perfect_without_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, false);
+      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, true);
+      check(result == perfect_with_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, false);
+      check(result == perfect_without_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, true);
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, false);
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             true);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_with_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
+      }
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             false);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_without_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
+      }
+    }
+
+  }
+
+  return 0;
+}
Index: test/gomory_hu_test.cc
===================================================================
--- test/gomory_hu_test.cc	(revision 643)
+++ test/gomory_hu_test.cc	(revision 956)
@@ -1,2 +1,20 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
 #include <iostream>
 
@@ -34,5 +52,5 @@
   "source 0\n"
   "target 3\n";
-  
+
 void checkGomoryHuCompile()
 {
@@ -70,5 +88,5 @@
 
 int cutValue(const Graph& graph, const BoolNodeMap& cut,
-	     const IntEdgeMap& capacity) {
+             const IntEdgeMap& capacity) {
 
   int sum = 0;
@@ -108,5 +126,5 @@
       int sum=0;
       for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
-        sum+=capacity[a]; 
+        sum+=capacity[a];
       check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
 
@@ -119,5 +137,5 @@
     }
   }
-  
+
   return 0;
 }
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 787)
+++ test/graph_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -265,5 +265,5 @@
   checkGraphEdgeList(G, 3);
   checkGraphArcList(G, 6);
-  
+
   G.addEdge(G.addNode(), G.addNode());
 
@@ -514,5 +514,5 @@
   G.resize(dim);
   check(G.dimension() == dim, "Wrong dimension");
-  
+
   checkGraphNodeList(G, 1 << dim);
   checkGraphEdgeList(G, dim * (1 << (dim-1)));
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 644)
+++ test/hao_orlin_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -84,5 +84,5 @@
 
 template <typename Graph, typename CapMap, typename CutMap>
-typename CapMap::Value 
+typename CapMap::Value
   cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
 {
@@ -111,5 +111,5 @@
     ho.run();
     ho.minCutMap(cut);
-    
+
     check(ho.minCutValue() == 1, "Wrong cut value");
     check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
@@ -127,17 +127,17 @@
     ho.run();
     ho.minCutMap(cut);
-    
+
     check(ho.minCutValue() == 1, "Wrong cut value");
     check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
   }
-  
+
   typedef Undirector<SmartDigraph> UGraph;
   UGraph ugraph(graph);
-  
+
   {
     HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
     ho.run();
     ho.minCutMap(cut);
-    
+
     check(ho.minCutValue() == 2, "Wrong cut value");
     check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
@@ -147,5 +147,5 @@
     ho.run();
     ho.minCutMap(cut);
-    
+
     check(ho.minCutValue() == 5, "Wrong cut value");
     check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
@@ -155,5 +155,5 @@
     ho.run();
     ho.minCutMap(cut);
-    
+
     check(ho.minCutValue() == 5, "Wrong cut value");
     check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 749)
+++ test/heap_test.cc	(revision 929)
@@ -31,10 +31,10 @@
 
 #include <lemon/bin_heap.h>
-#include <lemon/fourary_heap.h>
-#include <lemon/kary_heap.h>
+#include <lemon/quad_heap.h>
+#include <lemon/dheap.h>
 #include <lemon/fib_heap.h>
 #include <lemon/pairing_heap.h>
 #include <lemon/radix_heap.h>
-#include <lemon/binom_heap.h>
+#include <lemon/binomial_heap.h>
 #include <lemon/bucket_heap.h>
 
@@ -186,24 +186,24 @@
   }
 
-  // FouraryHeap
-  {
-    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
-    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
-    heapSortTest<IntHeap>();
-    heapIncreaseTest<IntHeap>();
-
-    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
-    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
-    dijkstraHeapTest<NodeHeap>(digraph, length, source);
-  }
-
-  // KaryHeap
-  {
-    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
-    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
-    heapSortTest<IntHeap>();
-    heapIncreaseTest<IntHeap>();
-
-    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
+  // QuadHeap
+  {
+    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // DHeap
+  {
+    typedef DHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef DHeap<Prio, IntNodeMap > NodeHeap;
     checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
@@ -246,12 +246,12 @@
   }
 
-  // BinomHeap
-  {
-    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
-    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
-    heapSortTest<IntHeap>();
-    heapIncreaseTest<IntHeap>();
-
-    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
+  // BinomialHeap
+  {
+    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
     checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 836)
+++ test/maps_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -226,5 +226,6 @@
 
     checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
-    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
+    MapToFunctor<ReadMap<A,B> > map =
+      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
 
     check(functorToMap(&func)[A()] == 3,
@@ -378,5 +379,5 @@
           it != map2.end(); ++it )
       check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
-    
+
     typedef ListDigraph Graph;
     DIGRAPH_TYPEDEFS(Graph);
@@ -387,5 +388,5 @@
     Node n2 = gr.addNode();
     Node n3 = gr.addNode();
-    
+
     gr.addArc(n3, n0);
     gr.addArc(n3, n2);
@@ -393,5 +394,5 @@
     gr.addArc(n2, n1);
     gr.addArc(n0, n1);
-    
+
     {
       std::vector<Node> v;
@@ -404,10 +405,10 @@
       std::vector<Node> v(countNodes(gr));
       dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
-      
+
       check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
             "Something is wrong with LoggerBoolMap");
     }
   }
-  
+
   // IdMap, RangeIdMap
   {
@@ -419,5 +420,5 @@
     checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
     checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
-    
+
     Graph gr;
     IdMap<Graph, Node> nmap(gr);
@@ -425,14 +426,14 @@
     RangeIdMap<Graph, Node> nrmap(gr);
     RangeIdMap<Graph, Arc> armap(gr);
-    
+
     Node n0 = gr.addNode();
     Node n1 = gr.addNode();
     Node n2 = gr.addNode();
-    
+
     Arc a0 = gr.addArc(n0, n1);
     Arc a1 = gr.addArc(n0, n2);
     Arc a2 = gr.addArc(n2, n1);
     Arc a3 = gr.addArc(n2, n0);
-    
+
     check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
     check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
@@ -446,5 +447,5 @@
     check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
     check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
-    
+
     check(nrmap.size() == 3 && armap.size() == 4,
           "Wrong RangeIdMap::size()");
@@ -453,5 +454,5 @@
     check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
     check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
-    
+
     check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
     check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
@@ -461,12 +462,12 @@
     check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
     check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
-    
+
     gr.erase(n1);
-    
+
     if (nrmap[n0] == 1) nrmap.swap(n0, n2);
     nrmap.swap(n2, n0);
     if (armap[a1] == 1) armap.swap(a1, a3);
     armap.swap(a3, a1);
-    
+
     check(nrmap.size() == 2 && armap.size() == 2,
           "Wrong RangeIdMap::size()");
@@ -474,5 +475,5 @@
     check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
     check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
-    
+
     check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
     check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
@@ -481,10 +482,10 @@
     check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
   }
-  
+
   // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
   {
     typedef ListGraph Graph;
     GRAPH_TYPEDEFS(Graph);
-    
+
     checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
     checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
@@ -498,5 +499,5 @@
     Node n1 = gr.addNode();
     Node n2 = gr.addNode();
-    
+
     gr.addEdge(n0,n1);
     gr.addEdge(n1,n2);
@@ -505,10 +506,10 @@
     gr.addEdge(n1,n2);
     gr.addEdge(n0,n1);
-    
+
     for (EdgeIt e(gr); e != INVALID; ++e) {
       check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
       check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
     }
-    
+
     check(mapCompare(gr,
           sourceMap(orienter(gr, constMap<Edge, bool>(true))),
@@ -520,8 +521,8 @@
     OutDegMap<Digraph> odm(dgr);
     InDegMap<Digraph> idm(dgr);
-    
+
     check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
     check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
-   
+
     gr.addEdge(n2, n0);
 
@@ -529,5 +530,5 @@
     check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
   }
-  
+
   // CrossRefMap
   {
@@ -541,17 +542,17 @@
     checkConcept<ReadWriteMap<Node, double>,
                  CrossRefMap<Graph, Node, double> >();
-    
+
     Graph gr;
     typedef CrossRefMap<Graph, Node, char> CRMap;
     CRMap map(gr);
-    
+
     Node n0 = gr.addNode();
     Node n1 = gr.addNode();
     Node n2 = gr.addNode();
-    
+
     map.set(n0, 'A');
     map.set(n1, 'B');
     map.set(n2, 'C');
-    
+
     check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
           "Wrong CrossRefMap");
@@ -562,9 +563,9 @@
     check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
           "Wrong CrossRefMap::count()");
-    
+
     CRMap::ValueIt it = map.beginValue();
     check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
           it == map.endValue(), "Wrong value iterator");
-    
+
     map.set(n2, 'A');
 
@@ -604,14 +605,14 @@
     checkConcept<ReadWriteMap<Node, int>,
                  CrossRefMap<Graph, Node, int> >();
-    
+
     Graph gr;
     typedef CrossRefMap<Graph, Node, char> CRMap;
     typedef CRMap::ValueIterator ValueIt;
     CRMap map(gr);
-    
+
     Node n0 = gr.addNode();
     Node n1 = gr.addNode();
     Node n2 = gr.addNode();
-    
+
     map.set(n0, 'A');
     map.set(n1, 'B');
@@ -630,5 +631,5 @@
           it == map.endValue(), "Wrong value iterator");
   }
-  
+
   // Iterable bool map
   {
@@ -818,5 +819,5 @@
 
   }
-  
+
   // Graph map utilities:
   // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
@@ -830,14 +831,14 @@
     Node n2 = g.addNode();
     Node n3 = g.addNode();
-    
+
     SmartDigraph::NodeMap<int> map1(g);
     SmartDigraph::ArcMap<char> map2(g);
     ConstMap<Node, A> cmap1 = A();
     ConstMap<Arc, C> cmap2 = C(0);
-    
+
     map1[n1] = 10;
     map1[n2] = 5;
     map1[n3] = 12;
-    
+
     // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
     check(mapMin(g, map1) == n2, "Wrong mapMin()");
@@ -858,5 +859,5 @@
     Arc a3 = g.addArc(n2, n3);
     Arc a4 = g.addArc(n3, n1);
-    
+
     map2[a1] = 'b';
     map2[a2] = 'a';
@@ -925,5 +926,5 @@
     check(mapCountIf(g, map2, Less<char>('a')) == 0,
           "Wrong mapCountIf()");
-     
+
     // MapIt, ConstMapIt
 /*
@@ -935,5 +936,5 @@
     check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
           "Wrong NodeMap<>::MapIt");
-    
+
     int sum = 0;
     std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
@@ -952,23 +953,23 @@
     SmartDigraph::NodeMap<int> map3(g, 0);
     SmartDigraph::ArcMap<char> map4(g, 'a');
-    
+
     check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
-    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");    
-    
+    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
+
     mapCopy(g, map1, map3);
     mapCopy(g, map2, map4);
 
     check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
-    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");    
-    
+    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
+
     Undirector<SmartDigraph> ug(g);
     Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
     Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
-    
+
     check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
     check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
     check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
     check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
-    
+
     mapCopy(g, map2, umap1);
 
@@ -977,14 +978,14 @@
     check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
     check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
-    
+
     mapCopy(g, map2, umap1);
     mapCopy(g, umap1, map2);
     mapCopy(ug, map2, umap1);
     mapCopy(ug, umap1, map2);
-    
+
     check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
     mapCopy(ug, umap1, umap2);
     check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
-    
+
     check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
     mapFill(g, map1, 2);
@@ -995,5 +996,5 @@
     check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
   }
-  
+
   return 0;
 }
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 641)
+++ test/matching_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -135,5 +135,5 @@
   mat_test.startDense();
   mat_test.run();
-  
+
   const_mat_test.matchingSize();
   const_mat_test.matching(e);
@@ -144,5 +144,5 @@
   const_mat_test.mate(n);
 
-  MaxMatching<Graph>::Status stat = 
+  MaxMatching<Graph>::Status stat =
     const_mat_test.status(n);
   const MaxMatching<Graph>::StatusMap& smap =
@@ -171,5 +171,5 @@
   mat_test.start();
   mat_test.run();
-  
+
   const_mat_test.matchingWeight();
   const_mat_test.matchingSize();
@@ -180,5 +180,5 @@
   e = mmap[n];
   const_mat_test.mate(n);
-  
+
   int k = 0;
   const_mat_test.dualValue();
@@ -208,5 +208,5 @@
   mat_test.start();
   mat_test.run();
-  
+
   const_mat_test.matchingWeight();
   const_mat_test.matching(e);
@@ -216,5 +216,5 @@
   e = mmap[n];
   const_mat_test.mate(n);
-  
+
   int k = 0;
   const_mat_test.dualValue();
@@ -402,20 +402,44 @@
       edgeMap("weight", weight).run();
 
-    MaxMatching<SmartGraph> mm(graph);
-    mm.run();
-    checkMatching(graph, mm);
-
-    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
-    mwm.run();
-    checkWeightedMatching(graph, weight, mwm);
-
-    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
-    bool perfect = mwpm.run();
-
-    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
-          "Perfect matching found");
-
-    if (perfect) {
-      checkWeightedPerfectMatching(graph, weight, mwpm);
+    bool perfect;
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.run();
+      checkMatching(graph, mm);
+      perfect = 2 * mm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.run();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.init();
+      mwm.start();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      bool result = mwpm.run();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      mwpm.init();
+      bool result = mwpm.start();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
     }
   }
Index: test/min_cost_arborescence_test.cc
===================================================================
--- test/min_cost_arborescence_test.cc	(revision 672)
+++ test/min_cost_arborescence_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -111,5 +111,5 @@
   b = const_mcarb_test.emptyQueue();
   i = const_mcarb_test.queueSize();
-  
+
   c = const_mcarb_test.arborescenceCost();
   b = const_mcarb_test.arborescence(e);
@@ -121,10 +121,10 @@
   b = const_mcarb_test.reached(n);
   b = const_mcarb_test.processed(n);
-  
+
   i = const_mcarb_test.dualNum();
   c = const_mcarb_test.dualValue();
   i = const_mcarb_test.dualSize(i);
   c = const_mcarb_test.dualValue(i);
-  
+
   ignore_unused_variable_warning(am);
   ignore_unused_variable_warning(pm);
Index: test/min_cost_flow_test.cc
===================================================================
--- test/min_cost_flow_test.cc	(revision 898)
+++ test/min_cost_flow_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -53,5 +53,5 @@
   "   11     0    0    0    0  -10    0\n"
   "   12   -20  -27    0  -30  -30  -20\n"
-  "\n"                
+  "\n"
   "@arcs\n"
   "       cost  cap low1 low2 low3\n"
@@ -103,5 +103,5 @@
   "6 7     30      0  -1000\n"
   "7 5   -120      0      0\n";
-  
+
 char test_neg2_lgf[] =
   "@nodes\n"
@@ -152,5 +152,5 @@
     void constraints() {
       checkConcept<concepts::Digraph, GR>();
-      
+
       const Constraints& me = *this;
 
@@ -181,5 +181,5 @@
     typedef concepts::WriteMap<Arc, Value> FlowMap;
     typedef concepts::WriteMap<Node, Cost> PotMap;
-  
+
     GR g;
     VAM lower;
@@ -235,5 +235,5 @@
            typename CM, typename SM, typename FM, typename PM >
 bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
-                     const CM& cost, const SM& supply, const FM& flow, 
+                     const CM& cost, const SM& supply, const FM& flow,
                      const PM& pi, SupplyType type )
 {
@@ -248,5 +248,5 @@
           (red_cost < 0 && flow[e] == upper[e]);
   }
-  
+
   for (NodeIt n(gr); opt && n != INVALID; ++n) {
     typename SM::Value sum = 0;
@@ -261,5 +261,5 @@
     }
   }
-  
+
   return opt;
 }
@@ -286,5 +286,5 @@
     }
   }
-  
+
   for (NodeIt n(gr); n != INVALID; ++n) {
     dual_cost -= red_supply[n] * pi[n];
@@ -295,5 +295,5 @@
     dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
   }
-  
+
   return dual_cost == total;
 }
@@ -333,5 +333,5 @@
 {
   MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
-  
+
   // Basic tests
   mcf1.upperMap(u).costMap(c).supplyMap(s1);
@@ -436,5 +436,5 @@
     .node("target", w)
     .run();
-  
+
   std::istringstream neg_inp1(test_neg1_lgf);
   DigraphReader<Digraph>(neg1_gr, neg_inp1)
@@ -444,5 +444,5 @@
     .nodeMap("sup", neg1_s)
     .run();
-  
+
   std::istringstream neg_inp2(test_neg2_lgf);
   DigraphReader<Digraph>(neg2_gr, neg_inp2)
@@ -450,5 +450,5 @@
     .nodeMap("sup", neg2_s)
     .run();
-  
+
   // Check the interface of NetworkSimplex
   {
@@ -502,5 +502,5 @@
 
   // Test NetworkSimplex
-  { 
+  {
     typedef NetworkSimplex<Digraph> MCF;
     runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
@@ -515,5 +515,5 @@
     runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
   }
-  
+
   // Test CapacityScaling
   {
Index: test/min_mean_cycle_test.cc
===================================================================
--- test/min_mean_cycle_test.cc	(revision 816)
+++ test/min_mean_cycle_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,7 +26,7 @@
 #include <lemon/concept_check.h>
 
-#include <lemon/karp.h>
-#include <lemon/hartmann_orlin.h>
-#include <lemon/howard.h>
+#include <lemon/karp_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
+#include <lemon/howard_mmc.h>
 
 #include "test_tools.h"
@@ -62,7 +62,7 @@
   "7 7    4    4    4   -1   0  0  0  1\n";
 
-                        
+
 // Check the interface of an MMC algorithm
-template <typename GR, typename Value>
+template <typename GR, typename Cost>
 struct MmcClassConcept
 {
@@ -74,28 +74,28 @@
       typedef typename MMC
         ::template SetPath<ListPath<GR> >
-        ::template SetLargeValue<Value>
+        ::template SetLargeCost<Cost>
         ::Create MmcAlg;
-      MmcAlg mmc(me.g, me.length);
+      MmcAlg mmc(me.g, me.cost);
       const MmcAlg& const_mmc = mmc;
-      
+
       typename MmcAlg::Tolerance tol = const_mmc.tolerance();
       mmc.tolerance(tol);
-      
+
       b = mmc.cycle(p).run();
-      b = mmc.findMinMean();
+      b = mmc.findCycleMean();
       b = mmc.findCycle();
 
-      v = const_mmc.cycleLength();
-      i = const_mmc.cycleArcNum();
+      v = const_mmc.cycleCost();
+      i = const_mmc.cycleSize();
       d = const_mmc.cycleMean();
       p = const_mmc.cycle();
     }
 
-    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
-  
+    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
+
     GR g;
-    LM length;
+    CM cost;
     ListPath<GR> p;
-    Value v;
+    Cost v;
     int i;
     double d;
@@ -109,11 +109,11 @@
                  const SmartDigraph::ArcMap<int>& lm,
                  const SmartDigraph::ArcMap<int>& cm,
-                 int length, int size) {
+                 int cost, int size) {
   MMC alg(gr, lm);
-  alg.findMinMean();
-  check(alg.cycleMean() == static_cast<double>(length) / size,
+  alg.findCycleMean();
+  check(alg.cycleMean() == static_cast<double>(cost) / size,
         "Wrong cycle mean");
   alg.findCycle();
-  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
+  check(alg.cycleCost() == cost && alg.cycleSize() == size,
         "Wrong path");
   SmartDigraph::ArcMap<int> cycle(gr, 0);
@@ -149,26 +149,26 @@
     typedef concepts::Digraph GR;
 
-    // Karp
+    // KarpMmc
     checkConcept< MmcClassConcept<GR, int>,
-                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
     checkConcept< MmcClassConcept<GR, float>,
-                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
-    
-    // HartmannOrlin
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HartmannOrlinMmc
     checkConcept< MmcClassConcept<GR, int>,
-                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
     checkConcept< MmcClassConcept<GR, float>,
-                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
-    
-    // Howard
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HowardMmc
     checkConcept< MmcClassConcept<GR, int>,
-                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
     checkConcept< MmcClassConcept<GR, float>,
-                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
-
-    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
-          long_int>::result == 0) check(false, "Wrong LargeValue type");
-    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
-          double>::result == 0) check(false, "Wrong LargeValue type");
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
+           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
+           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
   }
 
@@ -177,9 +177,9 @@
     typedef SmartDigraph GR;
     DIGRAPH_TYPEDEFS(GR);
-    
+
     GR gr;
     IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
     IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
-    
+
     std::istringstream input(test_lgf);
     digraphReader(gr, input).
@@ -195,20 +195,20 @@
 
     // Karp
-    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
-    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
-    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
-    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 
     // HartmannOrlin
-    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
-    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
-    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
-    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 
     // Howard
-    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
-    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
-    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
-    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
   }
 
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 736)
+++ test/preflow_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -95,5 +95,5 @@
   PreflowType preflow_test(g, cap, n, n);
   const PreflowType& const_preflow_test = preflow_test;
-  
+
   const PreflowType::Elevator& elev = const_preflow_test.elevator();
   preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
@@ -119,5 +119,5 @@
   b = const_preflow_test.minCut(n);
   const_preflow_test.minCutMap(cut);
-  
+
   ignore_unused_variable_warning(fm);
 }
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 670)
+++ test/suurballe_test.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,4 +24,5 @@
 #include <lemon/suurballe.h>
 #include <lemon/concepts/digraph.h>
+#include <lemon/concepts/heap.h>
 
 #include "test_tools.h"
@@ -81,6 +82,12 @@
   typedef Digraph::Arc Arc;
   typedef concepts::ReadMap<Arc, VType> LengthMap;
-  
-  typedef Suurballe<Digraph, LengthMap> SuurballeType;
+
+  typedef Suurballe<Digraph, LengthMap> ST;
+  typedef Suurballe<Digraph, LengthMap>
+    ::SetFlowMap<ST::FlowMap>
+    ::SetPotentialMap<ST::PotentialMap>
+    ::SetPath<SimplePath<Digraph> >
+    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
+    ::Create SuurballeType;
 
   Digraph g;
@@ -102,8 +109,11 @@
   k = suurb_test.run(n, n, k);
   suurb_test.init(n);
+  suurb_test.fullInit(n);
+  suurb_test.start(n);
+  suurb_test.start(n, k);
   k = suurb_test.findFlow(n);
   k = suurb_test.findFlow(n, k);
   suurb_test.findPaths();
-  
+
   int f;
   VType c;
@@ -117,5 +127,5 @@
   k = const_suurb_test.pathNum();
   Path<Digraph> p = const_suurb_test.path(k);
-  
+
   ignore_unused_variable_warning(fm);
   ignore_unused_variable_warning(pm);
@@ -196,7 +206,9 @@
     run();
 
-  // Find 2 paths
+  // Check run()
   {
     Suurballe<ListDigraph> suurballe(digraph, length);
+
+    // Find 2 paths
     check(suurballe.run(s, t) == 2, "Wrong number of paths");
     check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
@@ -208,9 +220,6 @@
     for (int i = 0; i < suurballe.pathNum(); ++i)
       check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
-  }
-
-  // Find 3 paths
-  {
-    Suurballe<ListDigraph> suurballe(digraph, length);
+
+    // Find 3 paths
     check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
     check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
@@ -222,9 +231,6 @@
     for (int i = 0; i < suurballe.pathNum(); ++i)
       check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
-  }
-
-  // Find 5 paths (only 3 can be found)
-  {
-    Suurballe<ListDigraph> suurballe(digraph, length);
+
+    // Find 5 paths (only 3 can be found)
     check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
     check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
@@ -238,4 +244,22 @@
   }
 
+  // Check fullInit() + start()
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    suurballe.fullInit(s);
+
+    // Find 2 paths
+    check(suurballe.start(t) == 2, "Wrong number of paths");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+
+    // Find 3 paths
+    check(suurballe.start(t, 3) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+
+    // Find 5 paths (only 3 can be found)
+    check(suurballe.start(t, 5) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+  }
+
   return 0;
 }
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 810)
+++ test/test_tools.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -46,5 +46,5 @@
     } else { }                                                          \
   }                                                                     \
-    
+
 
 #endif
Index: tools/dimacs-solver.cc
===================================================================
--- tools/dimacs-solver.cc	(revision 691)
+++ tools/dimacs-solver.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -89,8 +89,8 @@
   pre.run();
   if(report) std::cerr << "Run Preflow: " << ti << '\n';
-  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
-}
-
-template<class Value>
+  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
+}
+
+template<class Value, class LargeValue>
 void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
                Value infty, DimacsDescriptor &desc)
@@ -128,5 +128,6 @@
     std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
     std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
-    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
+    if (res) std::cerr << "Min flow cost: "
+                       << ns.template totalCost<LargeValue>() << '\n';
   }
 }
@@ -148,9 +149,9 @@
   if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
   if(report) std::cerr << "\nCardinality of max matching: "
-                       << mat.matchingSize() << '\n';  
-}
-
-
-template<class Value>
+                       << mat.matchingSize() << '\n';
+}
+
+
+template<class Value, class LargeValue>
 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
            DimacsDescriptor &desc)
@@ -166,9 +167,9 @@
       exit(1);
     }
-  
+
   switch(desc.type)
     {
     case DimacsDescriptor::MIN:
-      solve_min<Value>(ap,is,os,infty,desc);
+      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
       break;
     case DimacsDescriptor::MAX:
@@ -238,5 +239,5 @@
 
   DimacsDescriptor desc = dimacsType(is);
-  
+
   if(!ap.given("q"))
     {
@@ -263,14 +264,16 @@
       std::cout << "\n\n";
     }
-    
+
   if(ap.given("double"))
-    solve<double>(ap,is,os,desc);
+    solve<double, double>(ap,is,os,desc);
   else if(ap.given("ldouble"))
-    solve<long double>(ap,is,os,desc);
+    solve<long double, long double>(ap,is,os,desc);
 #ifdef LEMON_HAVE_LONG_LONG
   else if(ap.given("long"))
-    solve<long long>(ap,is,os,desc);
+    solve<long long, long long>(ap,is,os,desc);
+  else solve<int, long long>(ap,is,os,desc);
+#else
+  else solve<int, long>(ap,is,os,desc);
 #endif
-  else solve<int>(ap,is,os,desc);
 
   return 0;
