work/marci/bfs_iterator.h BfsIterator5 -> BfsIterator, DfsIterator5 -> DfsIterator
     3  *template <typename Item, 
 
     6  *          typename Compare = std::less<Prio> >
 
    10  *FibHeap(ItemIntMap),   FibHeap(ItemIntMap, Compare)
 
    14  *int size() : returns the number of elements in the heap
 
    16  *bool empty() : true iff size()=0
 
    18  *void set(Item, Prio) : calls push(Item, Prio) if Item is not
 
    19  *     in the heap, and calls decrease/increase(Item, Prio) otherwise
 
    21  *void push(Item, Prio) : pushes Item to the heap with priority Prio. Item
 
    22  *     mustn't be in the heap.
 
    24  *Item top() : returns the Item with least Prio. 
 
    25  *     Must be called only if heap is nonempty.
 
    27  *Prio prio() : returns the least Prio
 
    28  *     Must be called only if heap is nonempty.
 
    30  *Prio get(Item) : returns Prio of Item
 
    31  *     Must be called only if Item is in heap.
 
    33  *void pop() : deletes the Item with least Prio
 
    35  *void erase(Item) : deletes Item from the heap if it was already there
 
    37  *void decrease(Item, P) : decreases prio of Item to P. 
 
    38  *     Item must be in the heap with prio at least P.
 
    40  *void increase(Item, P) : sets prio of Item to P. 
 
    42  *state_enum state(Item) : returns PRE_HEAP if Item has not been in the 
 
    43  *     heap until now, IN_HEAP if it is in the heap at the moment, and 
 
    44  *     POST_HEAP otherwise. In the latter case it is possible that Item
 
    45  *     will get back to the heap again. 
 
    47  *In Fibonacci heaps, increase and erase are not efficient, in case of
 
    48  *many calls to these operations, it is better to use bin_heap.
 
    55 ///\brief Fibonacci Heap implementation.
 
    63   /// A Fibonacci Heap implementation.
 
    64   template <typename Item, typename Prio, typename ItemIntMap, 
 
    65 	    typename Compare = std::less<Prio> >
 
    68     typedef Prio PrioType;
 
    72     std::vector<store> container;
 
    78     ///\todo It is use nowhere
 
    79     ///\todo It doesn't conform to the naming conventions.
 
    89     FibHeap(ItemIntMap &_iimap) : minimum(), iimap(_iimap), num_items() {} 
 
    90     FibHeap(ItemIntMap &_iimap, const Compare &_comp) : minimum(), 
 
    91       iimap(_iimap), comp(_comp), num_items() {}
 
    99     bool empty() const { return num_items==0; }
 
   102     void set (Item const it, PrioType const value) {
 
   104       if ( i >= 0 && container[i].in ) {
 
   105 	if ( comp(value, container[i].prio) ) decrease(it, value); 
 
   106 	if ( comp(container[i].prio, value) ) increase(it, value); 
 
   107       } else push(it, value);
 
   111     void push (Item const it, PrioType const value) {
 
   114 	int s=container.size();
 
   118 	container.push_back(st);
 
   121 	container[i].parent=container[i].child=-1;
 
   122 	container[i].degree=0;
 
   123 	container[i].in=true;
 
   124 	container[i].marked=false;
 
   128 	container[container[minimum].right_neighbor].left_neighbor=i;
 
   129 	container[i].right_neighbor=container[minimum].right_neighbor;
 
   130 	container[minimum].right_neighbor=i;
 
   131 	container[i].left_neighbor=minimum;
 
   132 	if ( comp( value, container[minimum].prio) ) minimum=i; 
 
   134 	container[i].right_neighbor=container[i].left_neighbor=i;
 
   137       container[i].prio=value;
 
   143       return container[minimum].name;
 
   147     PrioType prio() const {
 
   148       return container[minimum].prio;
 
   154     PrioType& operator[](const Item& it) {
 
   155       return container[iimap[it]].prio;
 
   158     const PrioType& operator[](const Item& it) const {
 
   159       return container[iimap[it]].prio;
 
   162 //     const PrioType get(const Item& it) const {
 
   163 //       return container[iimap[it]].prio;
 
   167       /*The first case is that there are only one root.*/
 
   168       if ( container[minimum].left_neighbor==minimum ) {
 
   169 	container[minimum].in=false;
 
   170 	if ( container[minimum].degree!=0 ) { 
 
   171 	  makeroot(container[minimum].child);
 
   172 	  minimum=container[minimum].child;
 
   176 	int right=container[minimum].right_neighbor;
 
   178 	container[minimum].in=false;
 
   179 	if ( container[minimum].degree > 0 ) {
 
   180 	  int left=container[minimum].left_neighbor;
 
   181 	  int child=container[minimum].child;
 
   182 	  int last_child=container[child].left_neighbor;
 
   186 	  container[left].right_neighbor=child;
 
   187 	  container[child].left_neighbor=left;
 
   188 	  container[right].left_neighbor=last_child;
 
   189 	  container[last_child].right_neighbor=right;
 
   193       } // the case where there are more roots
 
   198     void erase (const Item& it) {
 
   201       if ( i >= 0 && container[i].in ) { 	
 
   202 	if ( container[i].parent!=-1 ) {
 
   203 	  int p=container[i].parent;
 
   207 	minimum=i;     //As if its prio would be -infinity
 
   213     void decrease (Item it, PrioType const value) {
 
   215       container[i].prio=value;
 
   216       int p=container[i].parent;
 
   218       if ( p!=-1 && comp(value, container[p].prio) ) {
 
   222       if ( comp(value, container[minimum].prio) ) minimum=i; 
 
   226     void increase (Item it, PrioType const value) {
 
   232     state_enum state(const Item &it) const {
 
   235 	if ( container[i].in ) i=0;
 
   238       return state_enum(i);
 
   246     int maxdeg=int( floor( 2.08*log(double(container.size()))))+1;
 
   248     std::vector<int> A(maxdeg,-1); 
 
   251      *Recall that now minimum does not point to the minimum prio element.
 
   252      *We set minimum to this during balance().
 
   254     int anchor=container[minimum].left_neighbor; 
 
   260 	if ( anchor==active ) end=true;
 
   261 	int d=container[active].degree;
 
   262 	next=container[active].right_neighbor;
 
   265 	  if( comp(container[active].prio, container[A[d]].prio) ) {
 
   278        while ( container[minimum].parent >=0 ) minimum=container[minimum].parent;
 
   282 	 if ( comp(container[s].prio, container[minimum].prio) ) minimum=s;
 
   283 	 s=container[s].right_neighbor;
 
   288     void makeroot (int c) {
 
   291 	container[s].parent=-1;
 
   292 	s=container[s].right_neighbor;
 
   297     void cut (int a, int b) {    
 
   299        *Replacing a from the children of b.
 
   301       --container[b].degree;
 
   303       if ( container[b].degree !=0 ) {
 
   304 	int child=container[b].child;
 
   306 	  container[b].child=container[child].right_neighbor;
 
   311       /*Lacing a to the roots.*/
 
   312       int right=container[minimum].right_neighbor;
 
   313       container[minimum].right_neighbor=a;
 
   314       container[a].left_neighbor=minimum;
 
   315       container[a].right_neighbor=right;
 
   316       container[right].left_neighbor=a;
 
   318       container[a].parent=-1;
 
   319       container[a].marked=false;
 
   325       if ( container[a].parent!=-1 ) {
 
   326 	int p=container[a].parent;
 
   328 	if ( container[a].marked==false ) container[a].marked=true;
 
   337     void fuse (int a, int b) {
 
   340       /*Lacing b under a.*/
 
   341       container[b].parent=a;
 
   343       if (container[a].degree==0) {
 
   344 	container[b].left_neighbor=b;
 
   345 	container[b].right_neighbor=b;
 
   346 	container[a].child=b;	
 
   348 	int child=container[a].child;
 
   349 	int last_child=container[child].left_neighbor;
 
   350 	container[child].left_neighbor=b;
 
   351 	container[b].right_neighbor=child;
 
   352 	container[last_child].right_neighbor=b;
 
   353 	container[b].left_neighbor=last_child;
 
   356       ++container[a].degree;
 
   358       container[b].marked=false;
 
   363      *It is invoked only if a has siblings.
 
   365     void unlace (int a) {      
 
   366       int leftn=container[a].left_neighbor;
 
   367       int rightn=container[a].right_neighbor;
 
   368       container[leftn].right_neighbor=rightn;
 
   369       container[rightn].left_neighbor=leftn;
 
   374       friend class FibHeap;
 
   386       store() : parent(-1), child(-1), degree(), marked(false), in(true) {}