# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1247099881 -7200
# Node ID d1a9224f1e305286f983295c5215b2fa7b8ae0bc
# Parent  9f529abcaebf13f19e61ba24fdd2c3631860af91
Add fourary, k-ary, pairing and binomial heaps (#301)
These structures were implemented by Dorian Batha.

diff -r 9f529abcaebf -r d1a9224f1e30 lemon/Makefile.am
--- a/lemon/Makefile.am	Thu Jun 11 23:13:24 2009 +0200
+++ b/lemon/Makefile.am	Thu Jul 09 02:38:01 2009 +0200
@@ -59,6 +59,7 @@
 	lemon/assert.h \
 	lemon/bfs.h \
 	lemon/bin_heap.h \
+	lemon/binom_heap.h \
 	lemon/bucket_heap.h \
 	lemon/cbc.h \
 	lemon/circulation.h \
@@ -78,12 +79,14 @@
 	lemon/error.h \
 	lemon/euler.h \
 	lemon/fib_heap.h \
+	lemon/fourary_heap.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
 	lemon/gomory_hu.h \
 	lemon/graph_to_eps.h \
 	lemon/grid_graph.h \
 	lemon/hypercube_graph.h \
+	lemon/kary_heap.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
 	lemon/lgf_reader.h \
@@ -99,6 +102,7 @@
 	lemon/min_cost_arborescence.h \
 	lemon/nauty_reader.h \
 	lemon/network_simplex.h \
+	lemon/pairing_heap.h \
 	lemon/path.h \
 	lemon/preflow.h \
 	lemon/radix_heap.h \
diff -r 9f529abcaebf -r d1a9224f1e30 lemon/binom_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/binom_heap.h	Thu Jul 09 02:38:01 2009 +0200
@@ -0,0 +1,506 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BINOM_HEAP_H
+#define LEMON_BINOM_HEAP_H
+
+///\file
+///\ingroup auxdat
+///\brief Binomial Heap implementation.
+
+#include <vector>
+#include <functional>
+#include <lemon/math.h>
+#include <lemon/counter.h>
+
+namespace lemon {
+
+  /// \ingroup auxdat
+  ///
+  ///\brief Binomial Heap.
+  ///
+  ///This class implements the \e Binomial \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 Compare 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 Binomial
+  ///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 _ItemIntMap A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param _Compare A class for the ordering of the priorities. The
+  ///default is \c std::less<_Prio>.
+  ///
+  ///\sa BinHeap
+  ///\sa Dijkstra
+  ///\author Dorian Batha
+
+#ifdef DOXYGEN
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare>
+#else
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare = std::less<_Prio> >
+#endif
+  class BinomHeap {
+  public:
+    typedef _ItemIntMap ItemIntMap;
+    typedef _Prio Prio;
+    typedef typename ItemIntMap::Key Item;
+    typedef std::pair<Item,Prio> Pair;
+    typedef _Compare Compare;
+
+  private:
+    class store;
+
+    std::vector<store> container;
+    int minimum, head;
+    ItemIntMap &iimap;
+    Compare comp;
+    int num_items;
+
+  public:
+    ///Status of the nodes
+    enum State {
+      ///The node is in the heap
+      IN_HEAP = 0,
+      ///The node has never been in the heap
+      PRE_HEAP = -1,
+      ///The node was in the heap but it got out of it
+      POST_HEAP = -2
+    };
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap should be given to the constructor, since it is
+    ///   used internally to handle the cross references.
+    explicit BinomHeap(ItemIntMap &_iimap)
+      : minimum(0), head(-1), iimap(_iimap), num_items() {}
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap 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.
+    BinomHeap(ItemIntMap &_iimap, const Compare &_comp)
+      : minimum(0), head(-1), iimap(_iimap), comp(_comp), num_items() {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// Returns the number of items stored in the heap.
+    int size() const { return num_items; }
+
+    /// \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_items==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() {
+      container.clear(); minimum=0; num_items=0; head=-1;
+    }
+
+    /// \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=iimap[item];
+      if ( i >= 0 && container[i].in ) {
+        if ( comp(value, container[i].prio) ) decrease(item, value);
+        if ( comp(container[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=iimap[item];
+      if ( i<0 ) {
+        int s=container.size();
+        iimap.set( item,s );
+        store st;
+        st.name=item;
+        container.push_back(st);
+        i=s;
+      }
+      else {
+        container[i].parent=container[i].right_neighbor=container[i].child=-1;
+        container[i].degree=0;
+        container[i].in=true;
+      }
+      container[i].prio=value;
+
+      if( 0==num_items ) { head=i; minimum=i; }
+      else { merge(i); }
+
+      minimum = find_min();
+
+      ++num_items;
+    }
+
+    /// \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 container[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 container[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 container[iimap[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() {
+      container[minimum].in=false;
+
+      int head_child=-1;
+      if ( container[minimum].child!=-1 ) {
+        int child=container[minimum].child;
+        int neighb;
+        int prev=-1;
+        while( child!=-1 ) {
+          neighb=container[child].right_neighbor;
+          container[child].parent=-1;
+          container[child].right_neighbor=prev;
+          head_child=child;
+          prev=child;
+          child=neighb;
+        }
+      }
+
+      // The first case is that there are only one root.
+      if ( -1==container[head].right_neighbor ) {
+        head=head_child;
+      }
+      // The case where there are more roots.
+      else {
+        if( head!=minimum )  { unlace(minimum); }
+        else { head=container[head].right_neighbor; }
+
+        merge(head_child);
+      }
+      minimum=find_min();
+      --num_items;
+    }
+
+    /// \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 Binomial heaps.
+    void erase (const Item& item) {
+      int i=iimap[item];
+      if ( i >= 0 && container[i].in ) {
+        decrease( item, container[minimum].prio-1 );
+        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=iimap[item];
+
+      if( comp( value,container[i].prio ) ) {
+        container[i].prio=value;
+
+        int p_loc=container[i].parent, loc=i;
+        int parent, child, neighb;
+
+        while( -1!=p_loc && comp(container[loc].prio,container[p_loc].prio) ) {
+
+          // parent set for other loc_child
+          child=container[loc].child;
+          while( -1!=child ) {
+            container[child].parent=p_loc;
+            child=container[child].right_neighbor;
+          }
+
+          // parent set for other p_loc_child
+          child=container[p_loc].child;
+          while( -1!=child ) {
+            container[child].parent=loc;
+            child=container[child].right_neighbor;
+          }
+
+          child=container[p_loc].child;
+          container[p_loc].child=container[loc].child;
+          if( child==loc )
+            child=p_loc;
+          container[loc].child=child;
+
+          // left_neighb set for p_loc
+          if( container[loc].child!=p_loc ) {
+            while( container[child].right_neighbor!=loc )
+              child=container[child].right_neighbor;
+            container[child].right_neighbor=p_loc;
+          }
+
+          // left_neighb set for loc
+          parent=container[p_loc].parent;
+          if( -1!=parent ) child=container[parent].child;
+          else child=head;
+
+          if( child!=p_loc ) {
+            while( container[child].right_neighbor!=p_loc )
+              child=container[child].right_neighbor;
+            container[child].right_neighbor=loc;
+          }
+
+          neighb=container[p_loc].right_neighbor;
+          container[p_loc].right_neighbor=container[loc].right_neighbor;
+          container[loc].right_neighbor=neighb;
+
+          container[p_loc].parent=loc;
+          container[loc].parent=parent;
+
+          if( -1!=parent && container[parent].child==p_loc )
+            container[parent].child=loc;
+
+          /*if new parent will be the first root*/
+          if( head==p_loc )
+            head=loc;
+
+          p_loc=container[loc].parent;
+        }
+      }
+      if( comp(value,container[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=iimap[item];
+      if( i>=0 ) {
+        if ( container[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);
+        }
+        iimap[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+    int find_min() {
+      int min_loc=-1, min_val;
+      int x=head;
+      if( x!=-1 ) {
+        min_val=container[x].prio;
+        min_loc=x;
+        x=container[x].right_neighbor;
+
+        while( x!=-1 ) {
+          if( comp( container[x].prio,min_val ) ) {
+            min_val=container[x].prio;
+            min_loc=x;
+          }
+          x=container[x].right_neighbor;
+        }
+      }
+      return min_loc;
+    }
+
+    void merge(int a) {
+      interleave(a);
+
+      int x=head;
+      if( -1!=x ) {
+        int x_prev=-1, x_next=container[x].right_neighbor;
+        while( -1!=x_next ) {
+          if( container[x].degree!=container[x_next].degree || ( -1!=container[x_next].right_neighbor && container[container[x_next].right_neighbor].degree==container[x].degree ) ) {
+            x_prev=x;
+            x=x_next;
+          }
+          else {
+            if( comp(container[x].prio,container[x_next].prio) ) {
+              container[x].right_neighbor=container[x_next].right_neighbor;
+              fuse(x_next,x);
+            }
+            else {
+              if( -1==x_prev ) { head=x_next; }
+              else {
+                container[x_prev].right_neighbor=x_next;
+              }
+              fuse(x,x_next);
+              x=x_next;
+            }
+          }
+          x_next=container[x].right_neighbor;
+        }
+      }
+    }
+
+    void interleave(int a) {
+      int other=-1, head_other=-1;
+
+      while( -1!=a || -1!=head ) {
+        if( -1==a ) {
+          if( -1==head_other ) {
+            head_other=head;
+          }
+          else {
+            container[other].right_neighbor=head;
+          }
+          head=-1;
+        }
+        else if( -1==head ) {
+          if( -1==head_other ) {
+            head_other=a;
+          }
+          else {
+            container[other].right_neighbor=a;
+          }
+          a=-1;
+        }
+        else {
+          if( container[a].degree<container[head].degree ) {
+            if( -1==head_other ) {
+              head_other=a;
+            }
+            else {
+              container[other].right_neighbor=a;
+            }
+            other=a;
+            a=container[a].right_neighbor;
+          }
+          else {
+            if( -1==head_other ) {
+              head_other=head;
+            }
+            else {
+              container[other].right_neighbor=head;
+            }
+            other=head;
+            head=container[head].right_neighbor;
+          }
+        }
+      }
+      head=head_other;
+    }
+
+    // Lacing a under b
+    void fuse(int a, int b) {
+      container[a].parent=b;
+      container[a].right_neighbor=container[b].child;
+      container[b].child=a;
+
+      ++container[b].degree;
+    }
+
+    // It is invoked only if a has siblings.
+    void unlace(int a) {
+      int neighb=container[a].right_neighbor;
+      int other=head;
+
+      while( container[other].right_neighbor!=a )
+        other=container[other].right_neighbor;
+      container[other].right_neighbor=neighb;
+    }
+
+  private:
+
+    class store {
+      friend class BinomHeap;
+
+      Item name;
+      int parent;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      store() : parent(-1), right_neighbor(-1), child(-1), degree(0), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_BINOM_HEAP_H
+
diff -r 9f529abcaebf -r d1a9224f1e30 lemon/fourary_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/fourary_heap.h	Thu Jul 09 02:38:01 2009 +0200
@@ -0,0 +1,350 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_FOURARY_HEAP_H
+#define LEMON_FOURARY_HEAP_H
+
+///\ingroup auxdat
+///\file
+///\brief 4ary Heap implementation.
+
+#include <iostream>
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  ///\ingroup auxdat
+  ///
+  ///\brief A 4ary Heap implementation.
+  ///
+  ///This class implements the \e 4ary \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 Compare specifies the ordering of the priorities. In a heap
+  ///one can change the priority of an item, add or erase an item, etc.
+  ///
+  ///\param _Prio Type of the priority of the items.
+  ///\param _ItemIntMap A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param _Compare A class for the ordering of the priorities. The
+  ///default is \c std::less<_Prio>.
+  ///
+  ///\sa FibHeap
+  ///\sa Dijkstra
+  ///\author Dorian Batha
+
+  template <typename _Prio, typename _ItemIntMap,
+            typename _Compare = std::less<_Prio> >
+
+  class FouraryHeap {
+
+  public:
+    ///\e
+    typedef _ItemIntMap ItemIntMap;
+    ///\e
+    typedef _Prio Prio;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+    ///\e
+    typedef std::pair<Item,Prio> Pair;
+    ///\e
+    typedef _Compare Compare;
+
+    /// \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:
+    std::vector<Pair> data;
+    Compare comp;
+    ItemIntMap &iim;
+
+  public:
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param _iim 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 FouraryHeap(ItemIntMap &_iim) : iim(_iim) {}
+
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param _iim 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 _comp The comparator function object.
+    FouraryHeap(ItemIntMap &_iim, const Compare &_comp)
+      : iim(_iim), comp(_comp) {}
+
+    /// 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 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(); }
+
+  private:
+    static int parent(int i) { return (i-1)/4; }
+    static int firstChild(int i) { return 4*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return comp(p1.second, p2.second);
+    }
+
+    int find_min(const int child, const int length) {
+      int min=child;
+      if( child+3<length ) {
+        if( less(data[child+3], data[min]) )
+          min=child+3;
+        if( less(data[child+2], data[min]) )
+          min=child+2;
+        if( less(data[child+1], data[min]) )
+          min=child+1;
+      }
+      else if( child+2<length ) {
+        if( less(data[child+2], data[min]) )
+          min=child+2;
+        if( less(data[child+1], data[min]) )
+          min=child+1;
+      }
+      else if( child+1<length ) {
+        if( less(data[child+1], data[min]) )
+          min=child+1;
+      }
+      return min;
+    }
+
+    void bubble_up(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,data[par]) ) {
+        move(data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubble_down(int hole, Pair p, int length) {
+      int child = firstChild(hole);
+      while( child<length && length>1 ) {
+        child = find_min(child,length);
+        if( !less(data[child], p) )
+          goto ok;
+        move(data[child], hole);
+        hole = child;
+        child = firstChild(hole);
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      data[i] = p;
+      iim.set(p.first, i);
+    }
+
+  public:
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// Adds \c p.first to the heap with priority \c p.second.
+    /// \param p The pair to insert.
+    void push(const Pair &p) {
+      int n = data.size();
+      data.resize(n+1);
+      bubble_up(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given heap.
+    ///
+    /// 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) { push(Pair(i,p)); }
+
+    /// \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[0].first; }
+
+    /// \brief Returns the minimum priority relative to \c Compare.
+    ///
+    /// It returns the minimum priority relative to \c Compare.
+    /// \pre The heap must be nonempty.
+    Prio prio() const { return data[0].second; }
+
+    /// \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() {
+      int n = data.size()-1;
+      iim.set(data[0].first, POST_HEAP);
+      if (n>0) bubble_down(0, data[n], n);
+      data.pop_back();
+    }
+
+    /// \brief Deletes \c i from the heap.
+    ///
+    /// This method deletes item \c i from the heap.
+    /// \param i The item to erase.
+    /// \pre The item should be in the heap.
+    void erase(const Item &i) {
+      int h = iim[i];
+      int n = data.size()-1;
+      iim.set(data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(data[parent(h)], data[n]) )
+          bubble_down(h, data[n], n);
+        else
+          bubble_up(h, data[n]);
+      }
+      data.pop_back();
+    }
+
+    /// \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].second;
+    }
+
+    /// \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( comp(p, data[idx].second) )
+        bubble_up(idx, Pair(i,p));
+      else
+        bubble_down(idx, Pair(i,p), data.size());
+    }
+
+    /// \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];
+      bubble_up(idx, Pair(i,p));
+    }
+
+    /// \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];
+      bubble_down(idx, Pair(i,p), data.size());
+    }
+
+    /// \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;
+      }
+    }
+
+    /// \brief Replaces an item in the heap.
+    ///
+    /// The \c i item is replaced with \c j item. The \c i item should
+    /// be in the heap, while the \c j should be out of the heap. The
+    /// \c i item will out of the heap and \c j will be in the heap
+    /// with the same prioriority as prevoiusly the \c i item.
+    void replace(const Item& i, const Item& j) {
+      int idx = iim[i];
+      iim.set(i, iim[j]);
+      iim.set(j, idx);
+      data[idx].first = j;
+    }
+
+  }; // class FouraryHeap
+
+} // namespace lemon
+
+#endif // LEMON_FOURARY_HEAP_H
diff -r 9f529abcaebf -r d1a9224f1e30 lemon/kary_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/kary_heap.h	Thu Jul 09 02:38:01 2009 +0200
@@ -0,0 +1,342 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_KARY_HEAP_H
+#define LEMON_KARY_HEAP_H
+
+///\ingroup auxdat
+///\file
+///\brief Kary Heap implementation.
+
+#include <iostream>
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  ///\ingroup auxdat
+  ///
+  ///\brief A Kary Heap implementation.
+  ///
+  ///This class implements the \e Kary \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 Compare specifies the ordering of the priorities. In a heap
+  ///one can change the priority of an item, add or erase an item, etc.
+  ///
+  ///\param _Prio Type of the priority of the items.
+  ///\param _ItemIntMap A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param _Compare A class for the ordering of the priorities. The
+  ///default is \c std::less<_Prio>.
+  ///
+  ///\sa FibHeap
+  ///\sa Dijkstra
+  ///\author Dorian Batha
+
+  template <typename _Prio, typename _ItemIntMap,
+            typename _Compare = std::less<_Prio> >
+
+  class KaryHeap {
+
+  public:
+    ///\e
+    typedef _ItemIntMap ItemIntMap;
+    ///\e
+    typedef _Prio Prio;
+    ///\e
+    typedef typename ItemIntMap::Key Item;
+    ///\e
+    typedef std::pair<Item,Prio> Pair;
+    ///\e
+    typedef _Compare Compare;
+    ///\e
+
+    /// \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:
+    std::vector<Pair> data;
+    Compare comp;
+    ItemIntMap &iim;
+    int K;
+
+  public:
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param _iim 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 KaryHeap(ItemIntMap &_iim, const int &_K=32) : iim(_iim), K(_K) {}
+
+    /// \brief The constructor.
+    ///
+    /// The constructor.
+    /// \param _iim 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 _comp The comparator function object.
+    KaryHeap(ItemIntMap &_iim, const Compare &_comp, const int &_K=32)
+      : iim(_iim), comp(_comp), K(_K) {}
+
+
+    /// 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 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(); }
+
+  private:
+    int parent(int i) { return (i-1)/K; }
+    int first_child(int i) { return K*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return comp(p1.second, p2.second);
+    }
+
+    int find_min(const int child, const int length) {
+      int min=child, i=1;
+      while( i<K && child+i<length ) {
+        if( less(data[child+i], data[min]) )
+          min=child+i;
+        ++i;
+      }
+      return min;
+    }
+
+    void bubble_up(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,data[par]) ) {
+        move(data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubble_down(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = first_child(hole);
+        while( child<length ) {
+          child = find_min(child, length);
+          if( !less(data[child], p) )
+            goto ok;
+          move(data[child], hole);
+          hole = child;
+          child = first_child(hole);
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      data[i] = p;
+      iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// Adds \c p.first to the heap with priority \c p.second.
+    /// \param p The pair to insert.
+    void push(const Pair &p) {
+      int n = data.size();
+      data.resize(n+1);
+      bubble_up(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given heap.
+    ///
+    /// 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) { push(Pair(i,p)); }
+
+    /// \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[0].first; }
+
+    /// \brief Returns the minimum priority relative to \c Compare.
+    ///
+    /// It returns the minimum priority relative to \c Compare.
+    /// \pre The heap must be nonempty.
+    Prio prio() const { return data[0].second; }
+
+    /// \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() {
+      int n = data.size()-1;
+      iim.set(data[0].first, POST_HEAP);
+      if (n>0) bubble_down(0, data[n], n);
+      data.pop_back();
+    }
+
+    /// \brief Deletes \c i from the heap.
+    ///
+    /// This method deletes item \c i from the heap.
+    /// \param i The item to erase.
+    /// \pre The item should be in the heap.
+    void erase(const Item &i) {
+      int h = iim[i];
+      int n = data.size()-1;
+      iim.set(data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(data[parent(h)], data[n]) )
+          bubble_down(h, data[n], n);
+        else
+          bubble_up(h, data[n]);
+      }
+      data.pop_back();
+    }
+
+
+    /// \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].second;
+    }
+
+    /// \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( comp(p, data[idx].second) )
+        bubble_up(idx, Pair(i,p));
+      else
+        bubble_down(idx, Pair(i,p), data.size());
+    }
+
+    /// \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];
+      bubble_up(idx, Pair(i,p));
+    }
+
+    /// \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];
+      bubble_down(idx, Pair(i,p), data.size());
+    }
+
+    /// \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;
+      }
+    }
+
+    /// \brief Replaces an item in the heap.
+    ///
+    /// The \c i item is replaced with \c j item. The \c i item should
+    /// be in the heap, while the \c j should be out of the heap. The
+    /// \c i item will out of the heap and \c j will be in the heap
+    /// with the same prioriority as prevoiusly the \c i item.
+    void replace(const Item& i, const Item& j) {
+      int idx=iim[i];
+      iim.set(i, iim[j]);
+      iim.set(j, idx);
+      data[idx].first=j;
+    }
+
+  }; // class KaryHeap
+
+} // namespace lemon
+
+#endif // LEMON_KARY_HEAP_H
diff -r 9f529abcaebf -r d1a9224f1e30 lemon/pairing_heap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/pairing_heap.h	Thu Jul 09 02:38:01 2009 +0200
@@ -0,0 +1,469 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_PAIRING_HEAP_H
+#define LEMON_PAIRING_HEAP_H
+
+///\file
+///\ingroup auxdat
+///\brief Pairing Heap implementation.
+
+#include <vector>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup auxdat
+  ///
+  ///\brief Pairing Heap.
+  ///
+  ///This class implements the \e Pairing \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 Compare 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 Pairing
+  ///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 _ItemIntMap A read and writable Item int map, used internally
+  ///to handle the cross references.
+  ///\param _Compare A class for the ordering of the priorities. The
+  ///default is \c std::less<_Prio>.
+  ///
+  ///\sa BinHeap
+  ///\sa Dijkstra
+  ///\author Dorian Batha
+
+#ifdef DOXYGEN
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare>
+#else
+  template <typename _Prio,
+            typename _ItemIntMap,
+            typename _Compare = std::less<_Prio> >
+#endif
+  class PairingHeap {
+  public:
+    typedef _ItemIntMap ItemIntMap;
+    typedef _Prio Prio;
+    typedef typename ItemIntMap::Key Item;
+    typedef std::pair<Item,Prio> Pair;
+    typedef _Compare Compare;
+
+  private:
+    class store;
+
+    std::vector<store> container;
+    int minimum;
+    ItemIntMap &iimap;
+    Compare comp;
+    int num_items;
+
+  public:
+    ///Status of the nodes
+    enum State {
+      ///The node is in the heap
+      IN_HEAP = 0,
+      ///The node has never been in the heap
+      PRE_HEAP = -1,
+      ///The node was in the heap but it got out of it
+      POST_HEAP = -2
+    };
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap should be given to the constructor, since it is
+    ///   used internally to handle the cross references.
+    explicit PairingHeap(ItemIntMap &_iimap)
+      : minimum(0), iimap(_iimap), num_items(0) {}
+
+    /// \brief The constructor
+    ///
+    /// \c _iimap 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.
+    PairingHeap(ItemIntMap &_iimap, const Compare &_comp)
+      : minimum(0), iimap(_iimap), comp(_comp), num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// Returns the number of items stored in the heap.
+    int size() const { return num_items; }
+
+    /// \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_items==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() {
+      container.clear();
+      minimum = 0;
+      num_items = 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=iimap[item];
+      if ( i>=0 && container[i].in ) {
+        if ( comp(value, container[i].prio) ) decrease(item, value);
+        if ( comp(container[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=iimap[item];
+      if( i<0 ) {
+        int s=container.size();
+        iimap.set(item, s);
+        store st;
+        st.name=item;
+        container.push_back(st);
+        i=s;
+      } else {
+        container[i].parent=container[i].child=-1;
+        container[i].left_child=false;
+        container[i].degree=0;
+        container[i].in=true;
+      }
+
+      container[i].prio=value;
+
+      if ( num_items!=0 ) {
+        if ( comp( value, container[minimum].prio) ) {
+          fuse(i,minimum);
+          minimum=i;
+        }
+        else fuse(minimum,i);
+      }
+      else minimum=i;
+
+      ++num_items;
+    }
+
+    /// \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 container[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 container[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 container[iimap[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() {
+      int TreeArray[num_items];
+      int i=0, num_child=0, child_right = 0;
+      container[minimum].in=false;
+
+      if( -1!=container[minimum].child ) {
+        i=container[minimum].child;
+        TreeArray[num_child] = i;
+        container[i].parent = -1;
+        container[minimum].child = -1;
+
+        ++num_child;
+        int ch=-1;
+        while( container[i].child!=-1 ) {
+          ch=container[i].child;
+          if( container[ch].left_child && i==container[ch].parent ) {
+            i=ch;
+            //break;
+          } else {
+            if( container[ch].left_child ) {
+              child_right=container[ch].parent;
+              container[ch].parent = i;
+              --container[i].degree;
+            }
+            else {
+              child_right=ch;
+              container[i].child=-1;
+              container[i].degree=0;
+            }
+            container[child_right].parent = -1;
+            TreeArray[num_child] = child_right;
+            i = child_right;
+            ++num_child;
+          }
+        }
+
+        int other;
+        for( i=0; i<num_child-1; i+=2 ) {
+          if ( !comp(container[TreeArray[i]].prio,
+                     container[TreeArray[i+1]].prio) ) {
+            other=TreeArray[i];
+            TreeArray[i]=TreeArray[i+1];
+            TreeArray[i+1]=other;
+          }
+          fuse( TreeArray[i], TreeArray[i+1] );
+        }
+
+        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
+        while(i>=2) {
+          if ( comp(container[TreeArray[i]].prio,
+                    container[TreeArray[i-2]].prio) ) {
+            other=TreeArray[i];
+            TreeArray[i]=TreeArray[i-2];
+            TreeArray[i-2]=other;
+          }
+          fuse( TreeArray[i-2], TreeArray[i] );
+          i-=2;
+        }
+        minimum = TreeArray[0];
+      }
+
+      if ( 0==num_child ) {
+        minimum = container[minimum].child;
+      }
+
+      --num_items;
+    }
+
+    /// \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 Pairing heaps.
+    void erase (const Item& item) {
+      int i=iimap[item];
+      if ( i>=0 && container[i].in ) {
+        decrease( item, container[minimum].prio-1 );
+        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=iimap[item];
+      container[i].prio=value;
+      int p=container[i].parent;
+
+      if( container[i].left_child && i!=container[p].child ) {
+        p=container[p].parent;
+      }
+
+      if ( p!=-1 && comp(value,container[p].prio) ) {
+        cut(i,p);
+        if ( comp(container[minimum].prio,value) ) {
+          fuse(minimum,i);
+        } else {
+          fuse(i,minimum);
+          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=iimap[item];
+      if( i>=0 ) {
+        if( container[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);
+        iimap[i]=st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    void cut(int a, int b) {
+      int child_a;
+      switch (container[a].degree) {
+        case 2:
+          child_a = container[container[a].child].parent;
+          if( container[a].left_child ) {
+            container[child_a].left_child=true;
+            container[b].child=child_a;
+            container[child_a].parent=container[a].parent;
+          }
+          else {
+            container[child_a].left_child=false;
+            container[child_a].parent=b;
+            if( a!=container[b].child )
+              container[container[b].child].parent=child_a;
+            else
+              container[b].child=child_a;
+          }
+          --container[a].degree;
+          container[container[a].child].parent=a;
+          break;
+
+        case 1:
+          child_a = container[a].child;
+          if( !container[child_a].left_child ) {
+            --container[a].degree;
+            if( container[a].left_child ) {
+              container[child_a].left_child=true;
+              container[child_a].parent=container[a].parent;
+              container[b].child=child_a;
+            }
+            else {
+              container[child_a].left_child=false;
+              container[child_a].parent=b;
+              if( a!=container[b].child )
+                container[container[b].child].parent=child_a;
+              else
+                container[b].child=child_a;
+            }
+            container[a].child=-1;
+          }
+          else {
+            --container[b].degree;
+            if( container[a].left_child ) {
+              container[b].child =
+                (1==container[b].degree) ? container[a].parent : -1;
+            } else {
+              if (1==container[b].degree)
+                container[container[b].child].parent=b;
+              else
+                container[b].child=-1;
+            }
+          }
+          break;
+
+        case 0:
+          --container[b].degree;
+          if( container[a].left_child ) {
+            container[b].child =
+              (0!=container[b].degree) ? container[a].parent : -1;
+          } else {
+            if( 0!=container[b].degree )
+              container[container[b].child].parent=b;
+            else
+              container[b].child=-1;
+          }
+          break;
+      }
+      container[a].parent=-1;
+      container[a].left_child=false;
+    }
+
+    void fuse(int a, int b) {
+      int child_a = container[a].child;
+      int child_b = container[b].child;
+      container[a].child=b;
+      container[b].parent=a;
+      container[b].left_child=true;
+
+      if( -1!=child_a ) {
+        container[b].child=child_a;
+        container[child_a].parent=b;
+        container[child_a].left_child=false;
+        ++container[b].degree;
+
+        if( -1!=child_b ) {
+           container[b].child=child_b;
+           container[child_b].parent=child_a;
+        }
+      }
+      else { ++container[a].degree; }
+    }
+
+    class store {
+      friend class PairingHeap;
+
+      Item name;
+      int parent;
+      int child;
+      bool left_child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_PAIRING_HEAP_H
+
diff -r 9f529abcaebf -r d1a9224f1e30 test/heap_test.cc
--- a/test/heap_test.cc	Thu Jun 11 23:13:24 2009 +0200
+++ b/test/heap_test.cc	Thu Jul 09 02:38:01 2009 +0200
@@ -25,14 +25,17 @@
 #include <lemon/concepts/heap.h>
 
 #include <lemon/smart_graph.h>
-
 #include <lemon/lgf_reader.h>
 #include <lemon/dijkstra.h>
 #include <lemon/maps.h>
 
 #include <lemon/bin_heap.h>
+#include <lemon/fourary_heap.h>
+#include <lemon/kary_heap.h>
 #include <lemon/fib_heap.h>
+#include <lemon/pairing_heap.h>
 #include <lemon/radix_heap.h>
+#include <lemon/binom_heap.h>
 #include <lemon/bucket_heap.h>
 
 #include "test_tools.h"
@@ -89,18 +92,16 @@
 template <typename Heap>
 void heapSortTest() {
   RangeMap<int> map(test_len, -1);
-
   Heap heap(map);
 
   std::vector<int> v(test_len);
-
   for (int i = 0; i < test_len; ++i) {
     v[i] = test_seq[i];
     heap.push(i, v[i]);
   }
   std::sort(v.begin(), v.end());
   for (int i = 0; i < test_len; ++i) {
-    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
+    check(v[i] == heap.prio(), "Wrong order in heap sort.");
     heap.pop();
   }
 }
@@ -112,7 +113,6 @@
   Heap heap(map);
 
   std::vector<int> v(test_len);
-
   for (int i = 0; i < test_len; ++i) {
     v[i] = test_seq[i];
     heap.push(i, v[i]);
@@ -123,13 +123,11 @@
   }
   std::sort(v.begin(), v.end());
   for (int i = 0; i < test_len; ++i) {
-    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
+    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
     heap.pop();
   }
 }
 
-
-
 template <typename Heap>
 void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
                       Node source) {
@@ -144,7 +142,7 @@
     Node t = digraph.target(a);
     if (dijkstra.reached(s)) {
       check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
-             "Error in a shortest path tree!");
+             "Error in shortest path tree.");
     }
   }
 
@@ -153,7 +151,7 @@
       Arc a = dijkstra.predArc(n);
       Node s = digraph.source(a);
       check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
-             "Error in a shortest path tree!");
+             "Error in shortest path tree.");
     }
   }
 
@@ -175,6 +173,7 @@
     node("source", source).
     run();
 
+  // BinHeap
   {
     typedef BinHeap<Prio, ItemIntMap> IntHeap;
     checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
@@ -186,6 +185,31 @@
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
   }
 
+  // FouraryHeap
+  {
+    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // KaryHeap
+  {
+    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // FibHeap
   {
     typedef FibHeap<Prio, ItemIntMap> IntHeap;
     checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
@@ -197,6 +221,19 @@
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
   }
 
+  // PairingHeap
+//  {
+//    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
+//    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+//    heapSortTest<IntHeap>();
+//    heapIncreaseTest<IntHeap>();
+//
+//    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
+//    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+//    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+//  }
+
+  // RadixHeap
   {
     typedef RadixHeap<ItemIntMap> IntHeap;
     checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
@@ -208,6 +245,19 @@
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
   }
 
+  // BinomHeap
+  {
+    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // BucketHeap, SimpleBucketHeap
   {
     typedef BucketHeap<ItemIntMap> IntHeap;
     checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
@@ -217,8 +267,10 @@
     typedef BucketHeap<IntNodeMap > NodeHeap;
     checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
+
+    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
+    heapSortTest<SimpleIntHeap>();
   }
 
-
   return 0;
 }