# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1249213485 -7200
# Node ID 99124ea4f04829d51d1a8843cb14c64498fb4ecb
# Parent  6e8c27ee907910245a2f2142e853588b989b86c1# Parent  71939d63ae77ee88ef5f207525227357fe200c27
Merge

diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/Makefile.am
--- a/lemon/Makefile.am	Thu Jul 23 18:13:59 2009 +0200
+++ b/lemon/Makefile.am	Sun Aug 02 13:44:45 2009 +0200
@@ -59,6 +59,7 @@
 	lemon/assert.h \
 	lemon/bfs.h \
 	lemon/bin_heap.h \
+	lemon/bucket_heap.h \
 	lemon/cbc.h \
 	lemon/circulation.h \
 	lemon/clp.h \
@@ -76,6 +77,7 @@
 	lemon/elevator.h \
 	lemon/error.h \
 	lemon/euler.h \
+	lemon/fib_heap.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
 	lemon/gomory_hu.h \
@@ -99,6 +101,7 @@
 	lemon/network_simplex.h \
 	lemon/path.h \
 	lemon/preflow.h \
+	lemon/radix_heap.h \
 	lemon/radix_sort.h \
 	lemon/random.h \
 	lemon/smart_graph.h \
diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/bin_heap.h
--- a/lemon/bin_heap.h	Thu Jul 23 18:13:59 2009 +0200
+++ b/lemon/bin_heap.h	Sun Aug 02 13:44:45 2009 +0200
@@ -33,23 +33,23 @@
   ///
   ///\brief A Binary Heap implementation.
   ///
-  ///This class implements the \e binary \e heap data structure. 
-  /// 
+  ///This class implements the \e binary \e heap data structure.
+  ///
   ///A \e heap is a data structure for storing items with specified values
   ///called \e priorities in such a way that finding the item with minimum
-  ///priority is efficient. \c Comp specifies the ordering of the priorities.
+  ///priority is efficient. \c CMP specifies the ordering of the priorities.
   ///In a heap one can change the priority of an item, add or erase an
   ///item, etc.
   ///
   ///\tparam PR Type of the priority of the items.
   ///\tparam IM A read and writable item map with int values, used internally
   ///to handle the cross references.
-  ///\tparam Comp A functor class for the ordering of the priorities.
+  ///\tparam CMP A functor class for the ordering of the priorities.
   ///The default is \c std::less<PR>.
   ///
   ///\sa FibHeap
   ///\sa Dijkstra
-  template <typename PR, typename IM, typename Comp = std::less<PR> >
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
   class BinHeap {
 
   public:
@@ -62,7 +62,7 @@
     ///\e
     typedef std::pair<Item,Prio> Pair;
     ///\e
-    typedef Comp Compare;
+    typedef CMP Compare;
 
     /// \brief Type to represent the items states.
     ///
diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/bucket_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/bucket_heap.h	Sun Aug 02 13:44:45 2009 +0200
@@ -0,0 +1,567 @@
+/* -*- 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_BUCKET_HEAP_H
+#define LEMON_BUCKET_HEAP_H
+
+///\ingroup auxdat
+///\file
+///\brief Bucket Heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  namespace _bucket_heap_bits {
+
+    template <bool MIN>
+    struct DirectionTraits {
+      static bool less(int left, int right) {
+        return left < right;
+      }
+      static void increase(int& value) {
+        ++value;
+      }
+    };
+
+    template <>
+    struct DirectionTraits<false> {
+      static bool less(int left, int right) {
+        return left > right;
+      }
+      static void increase(int& value) {
+        --value;
+      }
+    };
+
+  }
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A Bucket Heap implementation.
+  ///
+  /// This class implements the \e bucket \e heap data structure. A \e heap
+  /// is a data structure for storing items with specified values called \e
+  /// priorities in such a way that finding the item with minimum priority is
+  /// efficient. The bucket heap is very simple implementation, it can store
+  /// only integer priorities and it stores for each priority in the
+  /// \f$ [0..C) \f$ range a list of items. So it should be used only when
+  /// the priorities are small. It is not intended to use as dijkstra heap.
+  ///
+  /// \param IM A read and write Item int map, used internally
+  /// to handle the cross references.
+  /// \param MIN If the given parameter is false then instead of the
+  /// minimum value the maximum can be retrivied with the top() and
+  /// prio() member functions.
+  template <typename IM, bool MIN = true>
+  class BucketHeap {
+
+  public:
+    /// \e
+    typedef typename IM::Key Item;
+    /// \e
+    typedef int Prio;
+    /// \e
+    typedef std::pair<Item, Prio> Pair;
+    /// \e
+    typedef IM ItemIntMap;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the items states.
+    ///
+    /// Each Item element have a state associated to it. It may 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.
+    };
+
+  public:
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param map should be given to the constructor, since it is used
+    /// internally to handle the cross references. The value of the map
+    /// should be PRE_HEAP (-1) for each element.
+    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
+
+    /// The number of items stored in the heap.
+    ///
+    /// \brief Returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Checks if the heap stores no items.
+    ///
+    /// Returns \c true if and only if the heap stores no items.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make empty this heap.
+    ///
+    /// Make empty this heap. It does not change the cross reference
+    /// map.  If you want to reuse a heap what is not surely empty you
+    /// should first clear the heap and after that you should set the
+    /// cross reference map for each item to \c PRE_HEAP.
+    void clear() {
+      _data.clear(); _first.clear(); _minimum = 0;
+    }
+
+  private:
+
+    void relocate_last(int idx) {
+      if (idx + 1 < int(_data.size())) {
+        _data[idx] = _data.back();
+        if (_data[idx].prev != -1) {
+          _data[_data[idx].prev].next = idx;
+        } else {
+          _first[_data[idx].value] = idx;
+        }
+        if (_data[idx].next != -1) {
+          _data[_data[idx].next].prev = idx;
+        }
+        _iim[_data[idx].item] = idx;
+      }
+      _data.pop_back();
+    }
+
+    void unlace(int idx) {
+      if (_data[idx].prev != -1) {
+        _data[_data[idx].prev].next = _data[idx].next;
+      } else {
+        _first[_data[idx].value] = _data[idx].next;
+      }
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = _data[idx].prev;
+      }
+    }
+
+    void lace(int idx) {
+      if (int(_first.size()) <= _data[idx].value) {
+        _first.resize(_data[idx].value + 1, -1);
+      }
+      _data[idx].next = _first[_data[idx].value];
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = idx;
+      }
+      _first[_data[idx].value] = idx;
+      _data[idx].prev = -1;
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// Adds \c p.first to the heap with priority \c p.second.
+    /// \param p The pair to insert.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// Adds \c i to the heap with priority \c p.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    void push(const Item &i, const Prio &p) {
+      int idx = _data.size();
+      _iim[i] = idx;
+      _data.push_back(BucketItem(i, p));
+      lace(idx);
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+    }
+
+    /// \brief Returns the item with minimum priority.
+    ///
+    /// This method returns the item with minimum priority.
+    /// \pre The heap must be nonempty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief Returns the minimum priority.
+    ///
+    /// It returns the minimum priority.
+    /// \pre The heap must be nonempty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Deletes the item with minimum priority.
+    ///
+    /// This method deletes the item with minimum priority from the heap.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocate_last(idx);
+    }
+
+    /// \brief Deletes \c i from the heap.
+    ///
+    /// This method deletes item \c i from the heap, if \c i was
+    /// already stored in the heap.
+    /// \param i The item to erase.
+    void erase(const Item &i) {
+      int idx = _iim[i];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocate_last(idx);
+    }
+
+
+    /// \brief Returns the priority of \c i.
+    ///
+    /// This function returns the priority of item \c i.
+    /// \pre \c i must be in the heap.
+    /// \param i The item.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].value;
+    }
+
+    /// \brief \c i gets to the heap with priority \c p independently
+    /// if \c i was already there.
+    ///
+    /// This method calls \ref push(\c i, \c p) if \c i is not stored
+    /// in the heap and sets the priority of \c i to \c p otherwise.
+    /// \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 (Direction::less(p, _data[idx].value)) {
+        decrease(i, p);
+      } else {
+        increase(i, p);
+      }
+    }
+
+    /// \brief Decreases the priority of \c i to \c p.
+    ///
+    /// This method decreases the priority of item \c i to \c p.
+    /// \pre \c i must be stored in the heap with priority at least \c
+    /// p relative to \c Compare.
+    /// \param i The item.
+    /// \param p The priority.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      lace(idx);
+    }
+
+    /// \brief Increases the priority of \c i to \c p.
+    ///
+    /// This method sets the priority of item \c i to \c p.
+    /// \pre \c i must be stored in the heap with priority at most \c
+    /// p relative to \c Compare.
+    /// \param i The item.
+    /// \param p The priority.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      lace(idx);
+    }
+
+    /// \brief Returns if \c item is in, has already been in, or has
+    /// never been in the heap.
+    ///
+    /// This method returns PRE_HEAP if \c item has never been in the
+    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
+    /// otherwise. In the latter case it is possible that \c item will
+    /// get back to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+    /// \brief Sets the state of the \c item in the heap.
+    ///
+    /// Sets the state of the \c item in the heap. It can be used to
+    /// manually clear the heap when it is important to achive the
+    /// 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:
+
+    struct BucketItem {
+      BucketItem(const Item& _item, int _value)
+        : item(_item), value(_value) {}
+
+      Item item;
+      int value;
+
+      int prev, next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    mutable int _minimum;
+
+  }; // class BucketHeap
+
+  /// \ingroup auxdat
+  ///
+  /// \brief A Simplified Bucket Heap implementation.
+  ///
+  /// This class implements a simplified \e bucket \e heap data
+  /// structure.  It does not provide some functionality but it faster
+  /// and simplier data structure than the BucketHeap. The main
+  /// difference is that the BucketHeap stores for every key a double
+  /// linked list while this class stores just simple lists. In the
+  /// other way it does not support erasing each elements just the
+  /// minimal and it does not supports key increasing, decreasing.
+  ///
+  /// \param IM A read and write Item int map, used internally
+  /// to handle the cross references.
+  /// \param MIN If the given parameter is false then instead of the
+  /// minimum value the maximum can be retrivied with the top() and
+  /// prio() member functions.
+  ///
+  /// \sa BucketHeap
+  template <typename IM, bool MIN = true >
+  class SimpleBucketHeap {
+
+  public:
+    typedef typename IM::Key Item;
+    typedef int Prio;
+    typedef std::pair<Item, Prio> Pair;
+    typedef IM ItemIntMap;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the items states.
+    ///
+    /// Each Item element have a state associated to it. It may 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.
+    };
+
+  public:
+
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param map should be given to the constructor, since it is used
+    /// internally to handle the cross references. The value of the map
+    /// should be PRE_HEAP (-1) for each element.
+    explicit SimpleBucketHeap(ItemIntMap &map)
+      : _iim(map), _free(-1), _num(0), _minimum(0) {}
+
+    /// \brief Returns the number of items stored in the heap.
+    ///
+    /// The number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Checks if the heap stores no items.
+    ///
+    /// Returns \c true if and only if the heap stores no items.
+    bool empty() const { return _num == 0; }
+
+    /// \brief Make empty this heap.
+    ///
+    /// Make empty this heap. It does not change the cross reference
+    /// map.  If you want to reuse a heap what is not surely empty you
+    /// should first clear the heap and after that you should set the
+    /// cross reference map for each item to \c PRE_HEAP.
+    void clear() {
+      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
+    }
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// Adds \c p.first to the heap with priority \c p.second.
+    /// \param p The pair to insert.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// Adds \c i to the heap with priority \c p.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    void push(const Item &i, const Prio &p) {
+      int idx;
+      if (_free == -1) {
+        idx = _data.size();
+        _data.push_back(BucketItem(i));
+      } else {
+        idx = _free;
+        _free = _data[idx].next;
+        _data[idx].item = i;
+      }
+      _iim[i] = idx;
+      if (p >= int(_first.size())) _first.resize(p + 1, -1);
+      _data[idx].next = _first[p];
+      _first[p] = idx;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      ++_num;
+    }
+
+    /// \brief Returns the item with minimum priority.
+    ///
+    /// This method returns the item with minimum priority.
+    /// \pre The heap must be nonempty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief Returns the minimum priority.
+    ///
+    /// It returns the minimum priority.
+    /// \pre The heap must be nonempty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Deletes the item with minimum priority.
+    ///
+    /// This method deletes the item with minimum priority from the heap.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      _first[_minimum] = _data[idx].next;
+      _data[idx].next = _free;
+      _free = idx;
+      --_num;
+    }
+
+    /// \brief Returns the priority of \c i.
+    ///
+    /// This function returns the priority of item \c i.
+    /// \warning This operator is not a constant time function
+    /// because it scans the whole data structure to find the proper
+    /// value.
+    /// \pre \c i must be in the heap.
+    /// \param i The item.
+    Prio operator[](const Item &i) const {
+      for (int k = 0; k < _first.size(); ++k) {
+        int idx = _first[k];
+        while (idx != -1) {
+          if (_data[idx].item == i) {
+            return k;
+          }
+          idx = _data[idx].next;
+        }
+      }
+      return -1;
+    }
+
+    /// \brief Returns if \c item is in, has already been in, or has
+    /// never been in the heap.
+    ///
+    /// This method returns PRE_HEAP if \c item has never been in the
+    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
+    /// otherwise. In the latter case it is possible that \c item will
+    /// get back to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+  private:
+
+    struct BucketItem {
+      BucketItem(const Item& _item)
+        : item(_item) {}
+
+      Item item;
+      int next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    int _free, _num;
+    mutable int _minimum;
+
+  }; // class SimpleBucketHeap
+
+}
+
+#endif
diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/fib_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/fib_heap.h	Sun Aug 02 13:44:45 2009 +0200
@@ -0,0 +1,468 @@
+/* -*- 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_FIB_HEAP_H
+#define LEMON_FIB_HEAP_H
+
+///\file
+///\ingroup auxdat
+///\brief Fibonacci Heap implementation.
+
+#include <vector>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup auxdat
+  ///
+  ///\brief Fibonacci Heap.
+  ///
+  ///This class implements the \e Fibonacci \e heap data structure. A \e heap
+  ///is a data structure for storing items with specified values called \e
+  ///priorities in such a way that finding the item with minimum priority is
+  ///efficient. \c CMP specifies the ordering of the priorities. In a heap
+  ///one can change the priority of an item, add or erase an item, etc.
+  ///
+  ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
+  ///heap. In case of many calls to these operations, it is better to use a
+  ///\ref BinHeap "binary heap".
+  ///
+  ///\param PRIO Type of the priority of the items.
+  ///\param IM A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param CMP A class for the ordering of the priorities. The
+  ///default is \c std::less<PRIO>.
+  ///
+  ///\sa BinHeap
+  ///\sa Dijkstra
+#ifdef DOXYGEN
+  template <typename PRIO, typename IM, typename CMP>
+#else
+  template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
+#endif
+  class FibHeap {
+  public:
+    ///\e
+    typedef IM ItemIntMap;
+    ///\e
+    typedef PRIO Prio;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+    ///\e
+    typedef std::pair<Item,Prio> Pair;
+    ///\e
+    typedef CMP Compare;
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _minimum;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num;
+
+  public:
+
+    /// \brief Type to represent the items states.
+    ///
+    /// Each Item element have a state associated to it. It may 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.
+    };
+
+    /// \brief The constructor
+    ///
+    /// \c map should be given to the constructor, since it is
+    ///   used internally to handle the cross references.
+    explicit FibHeap(ItemIntMap &map)
+      : _minimum(0), _iim(map), _num() {}
+
+    /// \brief The constructor
+    ///
+    /// \c map should be given to the constructor, since it is used
+    /// internally to handle the cross references. \c comp is an
+    /// object for ordering of the priorities.
+    FibHeap(ItemIntMap &map, const Compare &comp)
+      : _minimum(0), _iim(map), _comp(comp), _num() {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// Returns the number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Checks if the heap stores no items.
+    ///
+    ///   Returns \c true if and only if the heap stores no items.
+    bool empty() const { return _num==0; }
+
+    /// \brief Make empty this heap.
+    ///
+    /// Make empty this heap. It does not change the cross reference
+    /// map.  If you want to reuse a heap what is not surely empty you
+    /// should first clear the heap and after that you should set the
+    /// cross reference map for each item to \c PRE_HEAP.
+    void clear() {
+      _data.clear(); _minimum = 0; _num = 0;
+    }
+
+    /// \brief \c item gets to the heap with priority \c value independently
+    /// if \c item was already there.
+    ///
+    /// This method calls \ref push(\c item, \c value) if \c item is not
+    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
+    /// \ref increase(\c item, \c value) otherwise.
+    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 Adds \c item to the heap with priority \c value.
+    ///
+    /// Adds \c item to the heap with priority \c value.
+    /// \pre \c 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;
+        _data.push_back(st);
+        i=s;
+      } else {
+        _data[i].parent=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].marked=false;
+      }
+
+      if ( _num ) {
+        _data[_data[_minimum].right_neighbor].left_neighbor=i;
+        _data[i].right_neighbor=_data[_minimum].right_neighbor;
+        _data[_minimum].right_neighbor=i;
+        _data[i].left_neighbor=_minimum;
+        if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
+      } else {
+        _data[i].right_neighbor=_data[i].left_neighbor=i;
+        _minimum=i;
+      }
+      _data[i].prio=value;
+      ++_num;
+    }
+
+    /// \brief Returns the item with minimum priority relative to \c Compare.
+    ///
+    /// This method returns the item with minimum priority relative to \c
+    /// Compare.
+    /// \pre The heap must be nonempty.
+    Item top() const { return _data[_minimum].name; }
+
+    /// \brief Returns the minimum priority relative to \c Compare.
+    ///
+    /// It returns the minimum priority relative to \c Compare.
+    /// \pre The heap must be nonempty.
+    const Prio& prio() const { return _data[_minimum].prio; }
+
+    /// \brief Returns the priority of \c item.
+    ///
+    /// It returns the priority of \c item.
+    /// \pre \c item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Deletes the item with minimum priority relative to \c Compare.
+    ///
+    /// This method deletes the item with minimum priority relative to \c
+    /// Compare from the heap.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      /*The first case is that there are only one root.*/
+      if ( _data[_minimum].left_neighbor==_minimum ) {
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree!=0 ) {
+          makeroot(_data[_minimum].child);
+          _minimum=_data[_minimum].child;
+          balance();
+        }
+      } else {
+        int right=_data[_minimum].right_neighbor;
+        unlace(_minimum);
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree > 0 ) {
+          int left=_data[_minimum].left_neighbor;
+          int child=_data[_minimum].child;
+          int last_child=_data[child].left_neighbor;
+
+          makeroot(child);
+
+          _data[left].right_neighbor=child;
+          _data[child].left_neighbor=left;
+          _data[right].left_neighbor=last_child;
+          _data[last_child].right_neighbor=right;
+        }
+        _minimum=right;
+        balance();
+      } // the case where there are more roots
+      --_num;
+    }
+
+    /// \brief Deletes \c item from the heap.
+    ///
+    /// This method deletes \c item from the heap, if \c item was already
+    /// stored in the heap. It is quite inefficient in Fibonacci heaps.
+    void erase (const Item& item) {
+      int i=_iim[item];
+
+      if ( i >= 0 && _data[i].in ) {
+        if ( _data[i].parent!=-1 ) {
+          int p=_data[i].parent;
+          cut(i,p);
+          cascade(p);
+        }
+        _minimum=i;     //As if its prio would be -infinity
+        pop();
+      }
+    }
+
+    /// \brief Decreases the priority of \c item to \c value.
+    ///
+    /// This method decreases the priority of \c item to \c value.
+    /// \pre \c item must be stored in the heap with priority at least \c
+    ///   value relative to \c Compare.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      _data[i].prio=value;
+      int p=_data[i].parent;
+
+      if ( p!=-1 && _comp(value, _data[p].prio) ) {
+        cut(i,p);
+        cascade(p);
+      }
+      if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
+    }
+
+    /// \brief Increases the priority of \c item to \c value.
+    ///
+    /// This method sets the priority of \c item to \c value. Though
+    /// there is no precondition on the priority of \c item, this
+    /// method should be used only if it is indeed necessary to increase
+    /// (relative to \c Compare) the priority of \c item, because this
+    /// method is inefficient.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item, value);
+    }
+
+
+    /// \brief Returns if \c item is in, has already been in, or has never
+    /// been in the heap.
+    ///
+    /// This method returns PRE_HEAP if \c item has never been in the
+    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
+    /// otherwise. In the latter case it is possible that \c item will
+    /// get back to the heap again.
+    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 Sets the state of the \c item in the heap.
+    ///
+    /// Sets the state of the \c item in the heap. It can be used to
+    /// manually clear the heap when it is important to achive the
+    /// 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:
+
+    void balance() {
+
+      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
+
+      std::vector<int> A(maxdeg,-1);
+
+      /*
+       *Recall that now minimum does not point to the minimum prio element.
+       *We set minimum to this during balance().
+       */
+      int anchor=_data[_minimum].left_neighbor;
+      int next=_minimum;
+      bool end=false;
+
+      do {
+        int active=next;
+        if ( anchor==active ) end=true;
+        int d=_data[active].degree;
+        next=_data[active].right_neighbor;
+
+        while (A[d]!=-1) {
+          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
+            fuse(active,A[d]);
+          } else {
+            fuse(A[d],active);
+            active=A[d];
+          }
+          A[d]=-1;
+          ++d;
+        }
+        A[d]=active;
+      } while ( !end );
+
+
+      while ( _data[_minimum].parent >=0 )
+        _minimum=_data[_minimum].parent;
+      int s=_minimum;
+      int m=_minimum;
+      do {
+        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
+        s=_data[s].right_neighbor;
+      } while ( s != m );
+    }
+
+    void makeroot(int c) {
+      int s=c;
+      do {
+        _data[s].parent=-1;
+        s=_data[s].right_neighbor;
+      } while ( s != c );
+    }
+
+    void cut(int a, int b) {
+      /*
+       *Replacing a from the children of b.
+       */
+      --_data[b].degree;
+
+      if ( _data[b].degree !=0 ) {
+        int child=_data[b].child;
+        if ( child==a )
+          _data[b].child=_data[child].right_neighbor;
+        unlace(a);
+      }
+
+
+      /*Lacing a to the roots.*/
+      int right=_data[_minimum].right_neighbor;
+      _data[_minimum].right_neighbor=a;
+      _data[a].left_neighbor=_minimum;
+      _data[a].right_neighbor=right;
+      _data[right].left_neighbor=a;
+
+      _data[a].parent=-1;
+      _data[a].marked=false;
+    }
+
+    void cascade(int a) {
+      if ( _data[a].parent!=-1 ) {
+        int p=_data[a].parent;
+
+        if ( _data[a].marked==false ) _data[a].marked=true;
+        else {
+          cut(a,p);
+          cascade(p);
+        }
+      }
+    }
+
+    void fuse(int a, int b) {
+      unlace(b);
+
+      /*Lacing b under a.*/
+      _data[b].parent=a;
+
+      if (_data[a].degree==0) {
+        _data[b].left_neighbor=b;
+        _data[b].right_neighbor=b;
+        _data[a].child=b;
+      } else {
+        int child=_data[a].child;
+        int last_child=_data[child].left_neighbor;
+        _data[child].left_neighbor=b;
+        _data[b].right_neighbor=child;
+        _data[last_child].right_neighbor=b;
+        _data[b].left_neighbor=last_child;
+      }
+
+      ++_data[a].degree;
+
+      _data[b].marked=false;
+    }
+
+    /*
+     *It is invoked only if a has siblings.
+     */
+    void unlace(int a) {
+      int leftn=_data[a].left_neighbor;
+      int rightn=_data[a].right_neighbor;
+      _data[leftn].right_neighbor=rightn;
+      _data[rightn].left_neighbor=leftn;
+    }
+
+
+    class Store {
+      friend class FibHeap;
+
+      Item name;
+      int parent;
+      int left_neighbor;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool marked;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_FIB_HEAP_H
+
diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/maps.h
--- a/lemon/maps.h	Thu Jul 23 18:13:59 2009 +0200
+++ b/lemon/maps.h	Sun Aug 02 13:44:45 2009 +0200
@@ -22,6 +22,7 @@
 #include <iterator>
 #include <functional>
 #include <vector>
+#include <map>
 
 #include <lemon/core.h>
 
@@ -29,8 +30,6 @@
 ///\ingroup maps
 ///\brief Miscellaneous property maps
 
-#include <map>
-
 namespace lemon {
 
   /// \addtogroup maps
@@ -1818,7 +1817,7 @@
   /// \brief Provides an immutable and unique id for each item in a graph.
   ///
   /// IdMap provides a unique and immutable id for each item of the
-  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
+  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
   ///  - \b unique: different items get different ids,
   ///  - \b immutable: the id of an item does not change (even if you
   ///    delete other nodes).
@@ -2281,7 +2280,7 @@
     }
 
     /// \brief Gives back the item belonging to a \e RangeId
-    /// 
+    ///
     /// Gives back the item belonging to a \e RangeId.
     Item operator()(int id) const {
       return _inv_map[id];
@@ -2338,6 +2337,903 @@
     }
   };
 
+  /// \brief Dynamic iterable \c bool map.
+  ///
+  /// This class provides a special graph map type which can store a
+  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
+  /// For both \c true and \c false values it is possible to iterate on
+  /// the keys.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscription operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableIntMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableBoolMap
+    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
+  private:
+    typedef GR Graph;
+
+    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
+    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
+
+    std::vector<K> _array;
+    int _sep;
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef bool Value;
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+  private:
+
+    int position(const Key& key) const {
+      return Parent::operator[](key);
+    }
+
+  public:
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c bool type. It can be converted to
+    /// \c bool and it provides the same operators.
+    class Reference {
+      friend class IterableBoolMap;
+    private:
+      Reference(IterableBoolMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<bool>(value));
+         return *this;
+      }
+
+      operator bool() const {
+        return static_cast<const IterableBoolMap&>(_map)[_key];
+      }
+
+      Reference& operator=(bool value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator&=(bool value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(bool value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(bool value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+    private:
+      Key _key;
+      IterableBoolMap& _map;
+    };
+
+    /// \brief Constructor of the map with a default value.
+    ///
+    /// Constructor of the map with a default value.
+    explicit IterableBoolMap(const Graph& graph, bool def = false)
+      : Parent(graph) {
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = (def ? _array.size() : 0);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    bool operator[](const Key& key) const {
+      return position(key) < _sep;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, bool value) {
+      int pos = position(key);
+      if (value) {
+        if (pos < _sep) return;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+        ++_sep;
+      } else {
+        if (pos >= _sep) return;
+        --_sep;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+      }
+    }
+
+    /// \brief Set all items.
+    ///
+    /// Set all items in the map.
+    /// \note Constant time operation.
+    void setAll(bool value) {
+      _sep = (value ? _array.size() : 0);
+    }
+
+    /// \brief Returns the number of the keys mapped to \c true.
+    ///
+    /// Returns the number of the keys mapped to \c true.
+    int trueNum() const {
+      return _sep;
+    }
+
+    /// \brief Returns the number of the keys mapped to \c false.
+    ///
+    /// Returns the number of the keys mapped to \c false.
+    int falseNum() const {
+      return _array.size() - _sep;
+    }
+
+    /// \brief Iterator for the keys mapped to \c true.
+    ///
+    /// Iterator for the keys mapped to \c true. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class TrueIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c true.
+      /// \param map The IterableBoolMap.
+      explicit TrueIt(const IterableBoolMap& map)
+        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
+          _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      TrueIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to \c false.
+    ///
+    /// Iterator for the keys mapped to \c false. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class FalseIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c false.
+      /// \param map The IterableBoolMap.
+      explicit FalseIt(const IterableBoolMap& map)
+        : Parent(map._sep < int(map._array.size()) ?
+                 map._array.back() : INVALID), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      FalseIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to a given value.
+    ///
+    /// Iterator for the keys mapped to a given value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableBoolMap.
+      /// \param value The value.
+      ItemIt(const IterableBoolMap& map, bool value)
+        : Parent(value ? 
+                 (map._sep > 0 ?
+                  map._array[map._sep - 1] : INVALID) :
+                 (map._sep < int(map._array.size()) ?
+                  map._array.back() : INVALID)), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        int pos = _map->position(*this);
+        int _sep = pos >= _map->_sep ? _map->_sep : 0;
+        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      Parent::set(key, _array.size());
+      _array.push_back(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        Parent::set(keys[i], _array.size());
+        _array.push_back(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      int pos = position(key);
+      if (pos < _sep) {
+        --_sep;
+        Parent::set(_array[_sep], pos);
+        _array[pos] = _array[_sep];
+        Parent::set(_array.back(), _sep);
+        _array[_sep] = _array.back();
+        _array.pop_back();
+      } else {
+        Parent::set(_array.back(), pos);
+        _array[pos] = _array.back();
+        _array.pop_back();
+      }
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int pos = position(keys[i]);
+        if (pos < _sep) {
+          --_sep;
+          Parent::set(_array[_sep], pos);
+          _array[pos] = _array[_sep];
+          Parent::set(_array.back(), _sep);
+          _array[_sep] = _array.back();
+          _array.pop_back();
+        } else {
+          Parent::set(_array.back(), pos);
+          _array[pos] = _array.back();
+          _array.pop_back();
+        }
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = 0;
+    }
+
+    virtual void clear() {
+      _array.clear();
+      _sep = 0;
+      Parent::clear();
+    }
+
+  };
+
+
+  namespace _maps_bits {
+    template <typename Item>
+    struct IterableIntMapNode {
+      IterableIntMapNode() : value(-1) {}
+      IterableIntMapNode(int _value) : value(_value) {}
+      Item prev, next;
+      int value;
+    };
+  }
+
+  /// \brief Dynamic iterable integer map.
+  ///
+  /// This class provides a special graph map type which can store an
+  /// integer value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each non-negative value it is possible to iterate on the keys
+  /// mapped to the value.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscription operator.
+  ///
+  /// \note The size of the data structure depends on the largest
+  /// value in the map.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableBoolMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableIntMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef int Value;
+    /// The graph type
+    typedef GR Graph;
+
+    /// \brief Constructor of the map.
+    ///
+    /// Constructor of the map. It sets all values to -1.
+    explicit IterableIntMap(const Graph& graph)
+      : Parent(graph) {}
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableIntMap(const Graph& graph, int value)
+      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
+      if (value >= 0) {
+        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+          lace(it);
+        }
+      }
+    }
+
+  private:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        _first[node.value] = node.next;
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+      while (!_first.empty() && _first.back() == INVALID) {
+        _first.pop_back();
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.value >= int(_first.size())) {
+        _first.resize(node.value + 1, INVALID);
+      }
+      node.prev = INVALID;
+      node.next = _first[node.value];
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = key;
+      }
+      _first[node.value] = key;
+    }
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c int type. It can
+    /// be converted to \c int and it has the same operators.
+    class Reference {
+      friend class IterableIntMap;
+    private:
+      Reference(IterableIntMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<const int&>(value));
+         return *this;
+      }
+
+      operator const int&() const {
+        return static_cast<const IterableIntMap&>(_map)[_key];
+      }
+
+      Reference& operator=(int value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator++() {
+        _map.set(_key, _map[_key] + 1);
+        return *this;
+      }
+      int operator++(int) {
+        int value = _map[_key];
+        _map.set(_key, value + 1);
+        return value;
+      }
+      Reference& operator--() {
+        _map.set(_key, _map[_key] - 1);
+        return *this;
+      }
+      int operator--(int) {
+        int value = _map[_key];
+        _map.set(_key, value - 1);
+        return value;
+      }
+      Reference& operator+=(int value) {
+        _map.set(_key, _map[_key] + value);
+        return *this;
+      }
+      Reference& operator-=(int value) {
+        _map.set(_key, _map[_key] - value);
+        return *this;
+      }
+      Reference& operator*=(int value) {
+        _map.set(_key, _map[_key] * value);
+        return *this;
+      }
+      Reference& operator/=(int value) {
+        _map.set(_key, _map[_key] / value);
+        return *this;
+      }
+      Reference& operator%=(int value) {
+        _map.set(_key, _map[_key] % value);
+        return *this;
+      }
+      Reference& operator&=(int value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(int value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(int value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+      Reference& operator<<=(int value) {
+        _map.set(_key, _map[_key] << value);
+        return *this;
+      }
+      Reference& operator>>=(int value) {
+        _map.set(_key, _map[_key] >> value);
+        return *this;
+      }
+
+    private:
+      Key _key;
+      IterableIntMap& _map;
+    };
+
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+    /// \brief Gives back the maximal value plus one.
+    ///
+    /// Gives back the maximal value plus one.
+    int size() const {
+      return _first.size();
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableIntMap.
+      /// \param value The value.
+      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
+        if (value < 0 || value >= int(_map->_first.size())) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(_map->_first[value]);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableIntMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+    private:
+      const IterableIntMap* _map;
+    };
+
+  protected:
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::vector<Key> _first;
+  };
+
+  namespace _maps_bits {
+    template <typename Item, typename Value>
+    struct IterableValueMapNode {
+      IterableValueMapNode(Value _value = Value()) : value(_value) {}
+      Item prev, next;
+      Value value;
+    };
+  }
+
+  /// \brief Dynamic iterable map for comparable values.
+  ///
+  /// This class provides a special graph map type which can store an
+  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each value it is possible to iterate on the keys mapped to
+  /// the value.
+  ///
+  /// The map stores for each value a linked list with
+  /// the items which mapped to the value, and the values are stored
+  /// in balanced binary tree. The values of the map can be accessed
+  /// with stl compatible forward iterator.
+  ///
+  /// This type is not reference map, so it cannot be modified with
+  /// the subscription operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  /// \tparam V The value type of the map. It can be any comparable
+  /// value type.
+  ///
+  /// \see IterableBoolMap, IterableIntMap
+  /// \see CrossRefMap
+  template <typename GR, typename K, typename V>
+  class IterableValueMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef V Value;
+    /// The graph type
+    typedef GR Graph;
+
+  public:
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableValueMap(const Graph& graph,
+                              const Value& value = Value())
+      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+  protected:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        if (node.next != INVALID) {
+          _first[node.value] = node.next;
+        } else {
+          _first.erase(node.value);
+        }
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      typename std::map<Value, Key>::iterator it = _first.find(node.value);
+      if (it == _first.end()) {
+        node.prev = node.next = INVALID;
+        _first.insert(std::make_pair(node.value, key));
+      } else {
+        node.prev = INVALID;
+        node.next = it->second;
+        if (node.next != INVALID) {
+          Parent::operator[](node.next).prev = key;
+        }
+        it->second = key;
+      }
+    }
+
+  public:
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an stl compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
+    class ValueIterator
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class IterableValueMap;
+    private:
+      ValueIterator(typename std::map<Value, Key>::const_iterator _it)
+        : it(_it) {}
+    public:
+
+      ValueIterator() {}
+
+      ValueIterator& operator++() { ++it; return *this; }
+      ValueIterator operator++(int) {
+        ValueIterator tmp(*this);
+        operator++();
+        return tmp;
+      }
+
+      const Value& operator*() const { return it->first; }
+      const Value* operator->() const { return &(it->first); }
+
+      bool operator==(ValueIterator jt) const { return it == jt.it; }
+      bool operator!=(ValueIterator jt) const { return it != jt.it; }
+
+    private:
+      typename std::map<Value, Key>::const_iterator it;
+    };
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an stl compatible iterator to the
+    /// first value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIterator beginValue() const {
+      return ValueIterator(_first.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an stl compatible iterator after the
+    /// last value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIterator endValue() const {
+      return ValueIterator(_first.end());
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys which have the given value.
+      /// \param map The IterableValueMap
+      /// \param value The value
+      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
+        typename std::map<Value, Key>::const_iterator it =
+          map._first.find(value);
+        if (it == map._first.end()) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(it->second);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableValueMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+
+    private:
+      const IterableValueMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      unlace(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        lace(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::map<Value, Key> _first;
+  };
+
   /// \brief Map of the source nodes of arcs in a digraph.
   ///
   /// SourceMap provides access for the source node of each arc in a digraph,
@@ -2507,7 +3403,7 @@
   /// in constant time. On the other hand, the values are updated automatically
   /// whenever the digraph changes.
   ///
-  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
   /// may provide alternative ways to modify the digraph.
   /// The correct behavior of InDegMap is not guarantied if these additional
   /// features are used. For example the functions
@@ -2523,7 +3419,7 @@
       ::ItemNotifier::ObserverBase {
 
   public:
-    
+
     /// The graph type of InDegMap
     typedef GR Graph;
     typedef GR Digraph;
@@ -2637,7 +3533,7 @@
   /// in constant time. On the other hand, the values are updated automatically
   /// whenever the digraph changes.
   ///
-  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
   /// may provide alternative ways to modify the digraph.
   /// The correct behavior of OutDegMap is not guarantied if these additional
   /// features are used. For example the functions
diff -r 6e8c27ee9079 -r 99124ea4f048 lemon/radix_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/radix_heap.h	Sun Aug 02 13:44:45 2009 +0200
@@ -0,0 +1,433 @@
+/* -*- 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_RADIX_HEAP_H
+#define LEMON_RADIX_HEAP_H
+
+///\ingroup auxdat
+///\file
+///\brief Radix Heap implementation.
+
+#include <vector>
+#include <lemon/error.h>
+
+namespace lemon {
+
+
+  /// \ingroup auxdata
+  ///
+  /// \brief A Radix Heap implementation.
+  ///
+  /// This class implements the \e radix \e heap data structure. A \e heap
+  /// is a data structure for storing items with specified values called \e
+  /// priorities in such a way that finding the item with minimum priority is
+  /// efficient. This heap type can store only items with \e int priority.
+  /// In a heap one can change the priority of an item, add or erase an
+  /// item, but the priority cannot be decreased under the last removed
+  /// item's priority.
+  ///
+  /// \param IM A read and writable Item int map, used internally
+  /// to handle the cross references.
+  ///
+  /// \see BinHeap
+  /// \see Dijkstra
+  template <typename IM>
+  class RadixHeap {
+
+  public:
+    typedef typename IM::Key Item;
+    typedef int Prio;
+    typedef IM ItemIntMap;
+
+    /// \brief Exception thrown by RadixHeap.
+    ///
+    /// This Exception is thrown when a smaller priority
+    /// is inserted into the \e RadixHeap then the last time erased.
+    /// \see RadixHeap
+
+    class UnderFlowPriorityError : public Exception {
+    public:
+      virtual const char* what() const throw() {
+        return "lemon::RadixHeap::UnderFlowPriorityError";
+      }
+    };
+
+    /// \brief Type to represent the items states.
+    ///
+    /// Each Item element have a state associated to it. It may 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 ItemIntMap \e should be initialized in such way that it maps
+    /// PRE_HEAP (-1) to any element to be put in the heap...
+    enum State {
+      IN_HEAP = 0,
+      PRE_HEAP = -1,
+      POST_HEAP = -2
+    };
+
+  private:
+
+    struct RadixItem {
+      int prev, next, box;
+      Item item;
+      int prio;
+      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
+    };
+
+    struct RadixBox {
+      int first;
+      int min, size;
+      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
+    };
+
+    std::vector<RadixItem> data;
+    std::vector<RadixBox> boxes;
+
+    ItemIntMap &_iim;
+
+
+  public:
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    ///
+    /// \param map It should be given to the constructor, since it is used
+    /// internally to handle the cross references. The value of the map
+    /// should be PRE_HEAP (-1) for each element.
+    ///
+    /// \param minimal The initial minimal value of the heap.
+    /// \param capacity It determines the initial capacity of the heap.
+    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
+      : _iim(map) {
+      boxes.push_back(RadixBox(minimal, 1));
+      boxes.push_back(RadixBox(minimal + 1, 1));
+      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
+        extend();
+      }
+    }
+
+    /// The number of items stored in the heap.
+    ///
+    /// \brief Returns the number of items stored in the heap.
+    int size() const { return data.size(); }
+    /// \brief Checks if the heap stores no items.
+    ///
+    /// Returns \c true if and only if the heap stores no items.
+    bool empty() const { return data.empty(); }
+
+    /// \brief Make empty this heap.
+    ///
+    /// Make empty this heap. It does not change the cross reference
+    /// map.  If you want to reuse a heap what is not surely empty you
+    /// should first clear the heap and after that you should set the
+    /// cross reference map for each item to \c PRE_HEAP.
+    void clear(int minimal = 0, int capacity = 0) {
+      data.clear(); boxes.clear();
+      boxes.push_back(RadixBox(minimal, 1));
+      boxes.push_back(RadixBox(minimal + 1, 1));
+      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
+        extend();
+      }
+    }
+
+  private:
+
+    bool upper(int box, Prio pr) {
+      return pr < boxes[box].min;
+    }
+
+    bool lower(int box, Prio pr) {
+      return pr >= boxes[box].min + boxes[box].size;
+    }
+
+    /// \brief Remove item from the box list.
+    void remove(int index) {
+      if (data[index].prev >= 0) {
+        data[data[index].prev].next = data[index].next;
+      } else {
+        boxes[data[index].box].first = data[index].next;
+      }
+      if (data[index].next >= 0) {
+        data[data[index].next].prev = data[index].prev;
+      }
+    }
+
+    /// \brief Insert item into the box list.
+    void insert(int box, int index) {
+      if (boxes[box].first == -1) {
+        boxes[box].first = index;
+        data[index].next = data[index].prev = -1;
+      } else {
+        data[index].next = boxes[box].first;
+        data[boxes[box].first].prev = index;
+        data[index].prev = -1;
+        boxes[box].first = index;
+      }
+      data[index].box = box;
+    }
+
+    /// \brief Add a new box to the box list.
+    void extend() {
+      int min = boxes.back().min + boxes.back().size;
+      int bs = 2 * boxes.back().size;
+      boxes.push_back(RadixBox(min, bs));
+    }
+
+    /// \brief Move an item up into the proper box.
+    void bubble_up(int index) {
+      if (!lower(data[index].box, data[index].prio)) return;
+      remove(index);
+      int box = findUp(data[index].box, data[index].prio);
+      insert(box, index);
+    }
+
+    /// \brief Find up the proper box for the item with the given prio.
+    int findUp(int start, int pr) {
+      while (lower(start, pr)) {
+        if (++start == int(boxes.size())) {
+          extend();
+        }
+      }
+      return start;
+    }
+
+    /// \brief Move an item down into the proper box.
+    void bubble_down(int index) {
+      if (!upper(data[index].box, data[index].prio)) return;
+      remove(index);
+      int box = findDown(data[index].box, data[index].prio);
+      insert(box, index);
+    }
+
+    /// \brief Find up the proper box for the item with the given prio.
+    int findDown(int start, int pr) {
+      while (upper(start, pr)) {
+        if (--start < 0) throw UnderFlowPriorityError();
+      }
+      return start;
+    }
+
+    /// \brief Find the first not empty box.
+    int findFirst() {
+      int first = 0;
+      while (boxes[first].first == -1) ++first;
+      return first;
+    }
+
+    /// \brief Gives back the minimal prio of the box.
+    int minValue(int box) {
+      int min = data[boxes[box].first].prio;
+      for (int k = boxes[box].first; k != -1; k = data[k].next) {
+        if (data[k].prio < min) min = data[k].prio;
+      }
+      return min;
+    }
+
+    /// \brief Rearrange the items of the heap and makes the
+    /// first box not empty.
+    void moveDown() {
+      int box = findFirst();
+      if (box == 0) return;
+      int min = minValue(box);
+      for (int i = 0; i <= box; ++i) {
+        boxes[i].min = min;
+        min += boxes[i].size;
+      }
+      int curr = boxes[box].first, next;
+      while (curr != -1) {
+        next = data[curr].next;
+        bubble_down(curr);
+        curr = next;
+      }
+    }
+
+    void relocate_last(int index) {
+      if (index != int(data.size()) - 1) {
+        data[index] = data.back();
+        if (data[index].prev != -1) {
+          data[data[index].prev].next = index;
+        } else {
+          boxes[data[index].box].first = index;
+        }
+        if (data[index].next != -1) {
+          data[data[index].next].prev = index;
+        }
+        _iim[data[index].item] = index;
+      }
+      data.pop_back();
+    }
+
+  public:
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// Adds \c i to the heap with priority \c p.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    void push(const Item &i, const Prio &p) {
+      int n = data.size();
+      _iim.set(i, n);
+      data.push_back(RadixItem(i, p));
+      while (lower(boxes.size() - 1, p)) {
+        extend();
+      }
+      int box = findDown(boxes.size() - 1, p);
+      insert(box, n);
+    }
+
+    /// \brief Returns the item with minimum priority.
+    ///
+    /// This method returns the item with minimum priority.
+    /// \pre The heap must be nonempty.
+    Item top() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return data[boxes[0].first].item;
+    }
+
+    /// \brief Returns the minimum priority.
+    ///
+    /// It returns the minimum priority.
+    /// \pre The heap must be nonempty.
+    Prio prio() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return data[boxes[0].first].prio;
+     }
+
+    /// \brief Deletes the item with minimum priority.
+    ///
+    /// This method deletes the item with minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      moveDown();
+      int index = boxes[0].first;
+      _iim[data[index].item] = POST_HEAP;
+      remove(index);
+      relocate_last(index);
+    }
+
+    /// \brief Deletes \c i from the heap.
+    ///
+    /// This method deletes item \c i from the heap, if \c i was
+    /// already stored in the heap.
+    /// \param i The item to erase.
+    void erase(const Item &i) {
+      int index = _iim[i];
+      _iim[i] = POST_HEAP;
+      remove(index);
+      relocate_last(index);
+   }
+
+    /// \brief Returns the priority of \c i.
+    ///
+    /// This function returns the priority of item \c i.
+    /// \pre \c i must be in the heap.
+    /// \param i The item.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return data[idx].prio;
+    }
+
+    /// \brief \c i gets to the heap with priority \c p independently
+    /// if \c i was already there.
+    ///
+    /// This method calls \ref push(\c i, \c p) if \c i is not stored
+    /// in the heap and sets the priority of \c i to \c p otherwise.
+    /// It may throw an \e UnderFlowPriorityException.
+    /// \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( p >= data[idx].prio ) {
+        data[idx].prio = p;
+        bubble_up(idx);
+      } else {
+        data[idx].prio = p;
+        bubble_down(idx);
+      }
+    }
+
+
+    /// \brief Decreases the priority of \c i to \c p.
+    ///
+    /// This method decreases the priority of item \c i to \c p.
+    /// \pre \c i must be stored in the heap with priority at least \c p, and
+    /// \c should be greater or equal to the last removed item's priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      data[idx].prio = p;
+      bubble_down(idx);
+    }
+
+    /// \brief Increases the priority of \c i to \c p.
+    ///
+    /// This method sets the priority of item \c i to \c p.
+    /// \pre \c i must be stored in the heap with priority at most \c p
+    /// \param i The item.
+    /// \param p The priority.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      data[idx].prio = p;
+      bubble_up(idx);
+    }
+
+    /// \brief Returns if \c item is in, has already been in, or has
+    /// never been in the heap.
+    ///
+    /// This method returns PRE_HEAP if \c item has never been in the
+    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
+    /// otherwise. In the latter case it is possible that \c 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 Sets the state of the \c item in the heap.
+    ///
+    /// Sets the state of the \c item in the heap. It can be used to
+    /// manually clear the heap when it is important to achive the
+    /// 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;
+      }
+    }
+
+  }; // class RadixHeap
+
+} // namespace lemon
+
+#endif // LEMON_RADIX_HEAP_H
diff -r 6e8c27ee9079 -r 99124ea4f048 test/heap_test.cc
--- a/test/heap_test.cc	Thu Jul 23 18:13:59 2009 +0200
+++ b/test/heap_test.cc	Sun Aug 02 13:44:45 2009 +0200
@@ -31,6 +31,9 @@
 #include <lemon/maps.h>
 
 #include <lemon/bin_heap.h>
+#include <lemon/fib_heap.h>
+#include <lemon/radix_heap.h>
+#include <lemon/bucket_heap.h>
 
 #include "test_tools.h"
 
@@ -183,5 +186,39 @@
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
   }
 
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+
   return 0;
 }
diff -r 6e8c27ee9079 -r 99124ea4f048 test/maps_test.cc
--- a/test/maps_test.cc	Thu Jul 23 18:13:59 2009 +0200
+++ b/test/maps_test.cc	Sun Aug 02 13:44:45 2009 +0200
@@ -23,6 +23,7 @@
 #include <lemon/concepts/maps.h>
 #include <lemon/maps.h>
 #include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
 
 #include "test_tools.h"
 
@@ -494,5 +495,192 @@
           it == map.endValue(), "Wrong value iterator");
   }
 
+  // Iterable bool map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+
+    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
+    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
+
+    const int num = 10;
+    Graph g;
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ibm map1(g, true);
+    int n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
+    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
+
+    map1[items[5]] = true;
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+
+    map1[items[num / 2]] = false;
+    check(map1[items[num / 2]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 1, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 1, "Wrong number");
+
+    map1[items[0]] = false;
+    check(map1[items[0]] == false, "Wrong map value");
+
+    map1[items[num - 1]] = false;
+    check(map1[items[num - 1]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 3, "Wrong number");
+    check(map1.trueNum() == num - 3, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 3, "Wrong number");
+    check(map1.falseNum() == 3, "Wrong number");
+  }
+
+  // Iterable int map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
+
+    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
+
+    const int num = 10;
+    Graph g;
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Iim map1(g);
+    check(map1.size() == 0, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i;
+    }
+    check(map1.size() == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Iim::ItemIt it(map1, i);
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i % 2;
+    }
+    check(map1.size() == 2, "Wrong size");
+
+    int n = 0;
+    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
+
+  // Iterable value map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
+
+    checkConcept<ReadWriteMap<Item, double>, Ivm>();
+
+    const int num = 10;
+    Graph g;
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ivm map1(g, 0.0);
+    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
+    check(*map1.beginValue() == 0.0, "Wrong value");
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Ivm::ItemIt it(map1, static_cast<double>(i));
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (Ivm::ValueIterator vit = map1.beginValue();
+         vit != map1.endValue(); ++vit) {
+      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
+            "Wrong ValueIterator");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i % 2));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
+
+    int n = 0;
+    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
   return 0;
 }