Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 842)
+++ demo/arg_parser_demo.cc	(revision 440)
@@ -66,16 +66,7 @@
     .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)
-  // The try {} construct is necessary only if the ap.trowOnProblems()
-  // setting is in use.
-  try {
-    ap.parse();
-  } catch (ArgParserException &) { return 1; }
+  ap.parse();
 
   // Check each option if it has been given and print its value
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 842)
+++ lemon/arg_parser.cc	(revision 440)
@@ -21,21 +21,12 @@
 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();
-    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
+    exit(1);
   }
 
   ArgParser::ArgParser(int argc, const char * const *argv)
-    :_argc(argc), _argv(argv), _command_name(argv[0]),
-    _exit_on_problems(true) {
+    :_argc(argc), _argv(argv), _command_name(argv[0]) {
     funcOption("-help","Print a short help message",_showHelp,this);
     synonym("help","-help");
@@ -352,5 +343,5 @@
         i!=_others_help.end();++i) showHelp(i);
     for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
-    _terminate(ArgParserException::HELP);
+    exit(1);
   }
 
@@ -361,5 +352,5 @@
     std::cerr << "\nType '" << _command_name <<
       " --help' to obtain a short summary on the usage.\n\n";
-    _terminate(ArgParserException::UNKNOWN_OPT);
+    exit(1);
   }
 
@@ -424,5 +415,5 @@
       std::cerr << "\nType '" << _command_name <<
         " --help' to obtain a short summary on the usage.\n\n";
-      _terminate(ArgParserException::INVALID_OPT);
+      exit(1);
     }
   }
Index: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 842)
+++ lemon/arg_parser.h	(revision 440)
@@ -34,42 +34,4 @@
 
 namespace lemon {
-
-  ///Exception used by ArgParser
-  class ArgParserException : public Exception {
-  public:
-    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
@@ -142,5 +104,5 @@
     std::string _command_name;
 
-    
+
   private:
     //Bind a function to an option.
@@ -154,8 +116,4 @@
                     const std::string &help,
                     void (*func)(void *),void *data);
-
-    bool _exit_on_problems;
-    
-    void _terminate(ArgParserException::Reason reason) const;
 
   public:
@@ -423,9 +381,4 @@
     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 844)
+++ lemon/bellman_ford.h	(revision 825)
@@ -29,5 +29,4 @@
 #include <lemon/error.h>
 #include <lemon/maps.h>
-#include <lemon/tolerance.h>
 #include <lemon/path.h>
 
@@ -36,5 +35,5 @@
 namespace lemon {
 
-  /// \brief Default operation traits for the BellmanFord algorithm class.
+  /// \brief Default OperationTraits for the BellmanFord algorithm class.
   ///  
   /// This operation traits class defines all computational operations
@@ -43,11 +42,9 @@
   /// If the numeric type does not have infinity value, then the maximum
   /// value is used as extremal infinity value.
-  ///
-  /// \see BellmanFordToleranceOperationTraits
   template <
     typename V, 
     bool has_inf = std::numeric_limits<V>::has_infinity>
   struct BellmanFordDefaultOperationTraits {
-    /// \brief Value type for the algorithm.
+    /// \e
     typedef V Value;
     /// \brief Gives back the zero value of the type.
@@ -88,49 +85,4 @@
   };
   
-  /// \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.
   ///
@@ -156,6 +108,5 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits,
-    /// BellmanFordToleranceOperationTraits
+    /// \see BellmanFordDefaultOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  
@@ -887,6 +838,5 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits,
-    /// BellmanFordToleranceOperationTraits
+    /// \see BellmanFordDefaultOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
 
Index: lemon/capacity_scaling.h
===================================================================
--- lemon/capacity_scaling.h	(revision 840)
+++ lemon/capacity_scaling.h	(revision 831)
@@ -140,8 +140,7 @@
 
     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:
@@ -800,13 +799,13 @@
       if (_factor > 1) {
         // With scaling
-        Value max_sup = 0, max_dem = 0, max_cap = 0;
-        for (int i = 0; i != _root; ++i) {
+        Value max_sup = 0, max_dem = 0;
+        for (int i = 0; i != _node_num; ++i) {
           Value ex = _excess[i];
           if ( ex > max_sup) max_sup =  ex;
           if (-ex > max_dem) max_dem = -ex;
-          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];
-          }
+        }
+        Value max_cap = 0;
+        for (int j = 0; j != _res_arc_num; ++j) {
+          if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
         }
         max_sup = std::min(std::min(max_sup, max_dem), max_cap);
Index: lemon/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 840)
+++ lemon/cost_scaling.h	(revision 831)
@@ -202,9 +202,8 @@
 
     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:
@@ -250,5 +249,4 @@
     bool _have_lower;
     Value _sum_supply;
-    int _sup_node_num;
 
     // Data structures for storing the digraph
@@ -279,10 +277,4 @@
     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;
@@ -837,9 +829,4 @@
       }
 
-      _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>
@@ -876,5 +863,5 @@
         for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
           int ra = _reverse[a];
-          _res_cap[a] = 0;
+          _res_cap[a] = 1;
           _res_cap[ra] = 0;
           _cost[a] = 0;
@@ -890,12 +877,5 @@
       // 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) {
@@ -936,173 +916,61 @@
       }
     }
-    
-    // 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) {
+
+    /// 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;
+
+      // Perform cost scaling phases
+      IntVector pred_arc(_res_node_num);
+      std::vector<int> path_nodes;
+      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[u] -= delta;
-            _excess[v] += delta;
+            _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
-    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;
+        
+        // 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];
         }
-      }
-    }
-
-    /// Execute the algorithm performing augment and relabel operations
-    void startAugment(int max_length = std::numeric_limits<int>::max()) {
-      // Paramters for heuristics
-      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
-      std::vector<int> path;
-      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
-                                        1 : _epsilon / _alpha )
-      {
-        // Early termination heuristic
-        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
-          if (earlyTermination()) break;
-        }
-        
-        // Initialize current phase
-        initPhase();
-        
+
         // Perform partial augment and relabel operations
         while (true) {
@@ -1114,18 +982,23 @@
           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.size()) < max_length) {
+          while (_excess[tip] >= 0 &&
+                 int(path_nodes.size()) <= max_length) {
             int u;
-            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
-            int last_out = _first_out[tip+1];
+            LargeCost min_red_cost, rc;
+            int last_out = _sum_supply < 0 ?
+              _first_out[tip+1] : _first_out[tip+1] - 1;
             for (int a = _next_out[tip]; a != last_out; ++a) {
-              u = _target[a];
-              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
-                path.push_back(a);
+              if (_res_cap[a] > 0 &&
+                  _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
+                u = _target[a];
+                pred_arc[u] = a;
                 _next_out[tip] = a;
                 tip = u;
+                path_nodes.push_back(tip);
                 goto next_step;
               }
@@ -1133,11 +1006,7 @@
 
             // Relabel tip node
-            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]];
-            }
+            min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
             for (int a = _first_out[tip]; a != last_out; ++a) {
-              rc = _cost[a] + pi_tip - _pi[_target[a]];
+              rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
               if (_res_cap[a] > 0 && rc < min_red_cost) {
                 min_red_cost = rc;
@@ -1145,11 +1014,12 @@
             }
             _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) {
-              tip = _source[path.back()];
-              path.pop_back();
+              path_nodes.pop_back();
+              tip = path_nodes.back();
             }
 
@@ -1159,9 +1029,9 @@
           // Augment along the found path (as much flow as possible)
           Value delta;
-          int pa, u, v = start;
-          for (int i = 0; i != int(path.size()); ++i) {
-            pa = path[i];
+          int u, v = path_nodes.front(), pa;
+          for (int i = 1; i < int(path_nodes.size()); ++i) {
             u = v;
-            v = _target[pa];
+            v = path_nodes[i];
+            pa = pred_arc[v];
             delta = std::min(_res_cap[pa], _excess[u]);
             _res_cap[pa] -= delta;
@@ -1172,10 +1042,4 @@
               _active_nodes.push_back(v);
           }
-
-          // Global update heuristic
-          if (relabel_cnt >= next_update_limit) {
-            globalUpdate();
-            next_update_limit += global_update_freq;
-          }
         }
       }
@@ -1185,44 +1049,73 @@
     void startPush() {
       // Paramters for heuristics
-      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;
-      
+      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
+      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
+
       // 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
-        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
-          if (earlyTermination()) break;
-        }
-        
-        // Initialize current phase
-        initPhase();
+        // "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];
+        }
 
         // Perform push and relabel operations
         while (_active_nodes.size() > 0) {
-          LargeCost min_red_cost, rc, pi_n;
+          LargeCost min_red_cost, rc;
           Value delta;
           int n, t, a, last_out = _res_arc_num;
 
+          // Select an active node (FIFO selection)
         next_node:
-          // Select an active node (FIFO selection)
           n = _active_nodes.front();
-          last_out = _first_out[n+1];
-          pi_n = _pi[n];
-          
+          last_out = _sum_supply < 0 ?
+            _first_out[n+1] : _first_out[n+1] - 1;
+
           // Perform push operations if there are admissible arcs
           if (_excess[n] > 0) {
             for (a = _next_out[n]; a != last_out; ++a) {
               if (_res_cap[a] > 0 &&
-                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
+                  _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
                 delta = std::min(_res_cap[a], _excess[n]);
                 t = _target[a];
@@ -1230,9 +1123,9 @@
                 // Push-look-ahead heuristic
                 Value ahead = -_excess[t];
-                int last_out_t = _first_out[t+1];
-                LargeCost pi_t = _pi[t];
+                int last_out_t = _sum_supply < 0 ?
+                  _first_out[t+1] : _first_out[t+1] - 1;
                 for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
                   if (_res_cap[ta] > 0 && 
-                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
+                      _cost[ta] + _pi[_source[ta]] - _pi[_target[ta]] < 0)
                     ahead += _res_cap[ta];
                   if (ahead >= delta) break;
@@ -1241,5 +1134,5 @@
 
                 // Push flow along the arc
-                if (ahead < delta && !hyper[t]) {
+                if (ahead < delta) {
                   _res_cap[a] -= ahead;
                   _res_cap[_reverse[a]] += ahead;
@@ -1248,5 +1141,4 @@
                   _active_nodes.push_front(t);
                   hyper[t] = true;
-                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
                   _next_out[n] = a;
                   goto next_node;
@@ -1271,8 +1163,7 @@
           // Relabel the node if it is still active (or hyper)
           if (_excess[n] > 0 || hyper[n]) {
-             min_red_cost = hyper[n] ? -hyper_cost[n] :
-               std::numeric_limits<LargeCost>::max();
+            min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
             for (int a = _first_out[n]; a != last_out; ++a) {
-              rc = _cost[a] + pi_n - _pi[_target[a]];
+              rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
               if (_res_cap[a] > 0 && rc < min_red_cost) {
                 min_red_cost = rc;
@@ -1280,7 +1171,8 @@
             }
             _pi[n] -= min_red_cost + _epsilon;
+            hyper[n] = false;
+
+            // Reset the next arc
             _next_out[n] = _first_out[n];
-            hyper[n] = false;
-            ++relabel_cnt;
           }
         
@@ -1292,12 +1184,4 @@
             _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/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 840)
+++ lemon/cycle_canceling.h	(revision 830)
@@ -145,9 +145,8 @@
     
     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:
@@ -200,5 +199,5 @@
     IntArcMap _arc_idb;
     IntVector _first_out;
-    BoolVector _forward;
+    CharVector _forward;
     IntVector _source;
     IntVector _target;
@@ -964,6 +963,6 @@
       DoubleVector pi(_res_node_num, 0.0);
       IntVector level(_res_node_num);
-      BoolVector reached(_res_node_num);
-      BoolVector processed(_res_node_num);
+      CharVector reached(_res_node_num);
+      CharVector processed(_res_node_num);
       IntVector pred_node(_res_node_num);
       IntVector pred_arc(_res_node_num);
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 838)
+++ lemon/graph_to_eps.h	(revision 786)
@@ -685,7 +685,7 @@
 #else
       os << bits::getWinFormattedDate();
-      os << std::endl;
 #endif
     }
+    os << std::endl;
 
     if (_autoArcWidthScale) {
Index: lemon/hartmann_orlin.h
===================================================================
--- lemon/hartmann_orlin.h	(revision 841)
+++ lemon/hartmann_orlin.h	(revision 825)
@@ -406,6 +406,6 @@
     /// \pre \ref run() or \ref findMinMean() must be called before
     /// using this function.
-    Value cycleLength() const {
-      return static_cast<Value>(_best_length);
+    LargeValue cycleLength() const {
+      return _best_length;
     }
 
Index: lemon/howard.h
===================================================================
--- lemon/howard.h	(revision 841)
+++ lemon/howard.h	(revision 825)
@@ -385,6 +385,6 @@
     /// \pre \ref run() or \ref findMinMean() must be called before
     /// using this function.
-    Value cycleLength() const {
-      return static_cast<Value>(_best_length);
+    LargeValue cycleLength() const {
+      return _best_length;
     }
 
Index: lemon/karp.h
===================================================================
--- lemon/karp.h	(revision 841)
+++ lemon/karp.h	(revision 825)
@@ -393,6 +393,6 @@
     /// \pre \ref run() or \ref findMinMean() must be called before
     /// using this function.
-    Value cycleLength() const {
-      return static_cast<Value>(_cycle_length);
+    LargeValue cycleLength() const {
+      return _cycle_length;
     }
 
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 840)
+++ lemon/network_simplex.h	(revision 830)
@@ -165,8 +165,7 @@
 
     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
@@ -215,6 +214,6 @@
     IntVector _last_succ;
     IntVector _dirty_revs;
-    BoolVector _forward;
-    BoolVector _state;
+    CharVector _forward;
+    CharVector _state;
     int _root;
 
@@ -247,5 +246,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const BoolVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -268,5 +267,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) {
@@ -276,5 +275,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) {
@@ -299,5 +298,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const BoolVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -316,5 +315,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) {
@@ -338,5 +337,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const BoolVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -357,5 +356,5 @@
       {
         // The main parameters of the pivot rule
-        const double BLOCK_SIZE_FACTOR = 1.0;
+        const double BLOCK_SIZE_FACTOR = 0.5;
         const int MIN_BLOCK_SIZE = 10;
 
@@ -370,5 +369,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) {
@@ -381,5 +380,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) {
@@ -411,5 +410,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const BoolVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -472,5 +471,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) {
@@ -483,5 +482,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) {
@@ -514,5 +513,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const BoolVector &_state;
+      const CharVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -567,5 +566,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] *
@@ -580,5 +579,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]]);
@@ -592,5 +591,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]]);
@@ -1362,5 +1361,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;
@@ -1432,98 +1431,4 @@
         _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;
     }
 
@@ -1550,7 +1455,4 @@
       PivotRuleImpl pivot(*this);
 
-      // Perform heuristic initial pivots
-      if (!initialPivots()) return UNBOUNDED;
-
       // Execute the Network Simplex algorithm
       while (pivot.findEnteringArc()) {
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 844)
+++ test/bellman_ford_test.cc	(revision 791)
@@ -105,5 +105,4 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
       ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
-      ::SetOperationTraits<BellmanFordToleranceOperationTraits<Value, 0> >
       ::Create bf_test(gr,length);
 
Index: tools/dimacs-solver.cc
===================================================================
--- tools/dimacs-solver.cc	(revision 644)
+++ tools/dimacs-solver.cc	(revision 846)
@@ -92,5 +92,5 @@
 }
 
-template<class Value>
+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';
   }
 }
@@ -152,5 +153,5 @@
 
 
-template<class Value>
+template<class Value, class LargeValue>
 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
            DimacsDescriptor &desc)
@@ -170,5 +171,5 @@
     {
     case DimacsDescriptor::MIN:
-      solve_min<Value>(ap,is,os,infty,desc);
+      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
       break;
     case DimacsDescriptor::MAX:
@@ -265,12 +266,14 @@
     
   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;
