src/work/jacint/prim.h
author alpar
Fri, 08 Apr 2005 15:22:46 +0000
changeset 1327 ecc1cdea2ee7
parent 921 818510fa3d99
permissions -rw-r--r--
Disable shared libraries (makes the compilation a bit faster)
jacint@173
     1
// -*- C++ -*-
jacint@173
     2
/* 
jacint@211
     3
 *template <Graph, T, Heap=FibHeap, LengthMap=Graph::EdgeMap<T> >
jacint@173
     4
 *
jacint@173
     5
 *Constructor: 
jacint@173
     6
 *
jacint@211
     7
 *Prim(Graph G, LengthMap weight)
jacint@173
     8
 *
jacint@173
     9
 *
jacint@173
    10
 *Methods:
jacint@173
    11
 *
jacint@211
    12
 *void run() : Runs the Prim-algorithm from a random node
jacint@173
    13
 *
jacint@211
    14
 *void run(Node r) : Runs the Prim-algorithm from node s
jacint@173
    15
 *
jacint@211
    16
 *T weight() : After run(r) was run, it returns the minimum 
jacint@211
    17
 *   weight of a spanning tree of the component of the root. 
jacint@173
    18
 *
jacint@211
    19
 *Edge tree(Node v) : After run(r) was run, it returns the 
jacint@211
    20
 *   first edge in the path from v to the root. Returns 
jacint@211
    21
 *   INVALID if v=r or v is not reachable from the root.
jacint@173
    22
 *
jacint@211
    23
 *bool conn() : After run(r) was run, it is true iff G is connected
jacint@173
    24
 *
jacint@211
    25
 *bool reached(Node v) : After run(r) was run, it is true 
jacint@211
    26
 *   iff v is in the same component as the root
jacint@173
    27
 *
jacint@211
    28
 *Node root() : returns the root
jacint@173
    29
 *
jacint@173
    30
 */
jacint@173
    31
alpar@921
    32
#ifndef LEMON_PRIM_H
alpar@921
    33
#define LEMON_PRIM_H
jacint@173
    34
jacint@173
    35
#include <fib_heap.h>
jacint@211
    36
#include <invalid.h>
jacint@173
    37
alpar@921
    38
namespace lemon {
jacint@173
    39
jacint@173
    40
  template <typename Graph, typename T, 
jacint@211
    41
    typename Heap=FibHeap<typename Graph::Node, T, 
jacint@211
    42
    typename Graph::NodeMap<int> >, 
jacint@211
    43
    typename LengthMap=typename Graph::EdgeMap<T> >
jacint@173
    44
    class Prim{
jacint@211
    45
      typedef typename Graph::Node Node;
jacint@173
    46
      typedef typename Graph::NodeIt NodeIt;
jacint@211
    47
      typedef typename Graph::Edge Edge;
jacint@173
    48
      typedef typename Graph::OutEdgeIt OutEdgeIt;
jacint@173
    49
      typedef typename Graph::InEdgeIt InEdgeIt;  
jacint@173
    50
jacint@211
    51
      const Graph& G;
jacint@211
    52
      const LengthMap& edge_weight;
jacint@211
    53
      typename Graph::NodeMap<Edge> tree_edge;
jacint@173
    54
      typename Graph::NodeMap<T> min_weight;
jacint@211
    55
      typename Graph::NodeMap<bool> reach;
jacint@173
    56
          
jacint@173
    57
  public :
jacint@173
    58
jacint@211
    59
      Prim(Graph& _G, LengthMap& _edge_weight) : 
jacint@211
    60
	G(_G), edge_weight(_edge_weight), 
jacint@211
    61
	tree_edge(_G,INVALID), min_weight(_G), reach(_G, false) { }
jacint@173
    62
jacint@211
    63
jacint@211
    64
      void run() {
jacint@211
    65
	NodeIt _r;	
jacint@211
    66
	G.first(_r);
jacint@211
    67
	run(_r);
jacint@173
    68
      }
jacint@173
    69
jacint@173
    70
jacint@211
    71
      void run(Node r) {
jacint@211
    72
jacint@211
    73
	NodeIt u;
jacint@211
    74
	for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
jacint@211
    75
	  tree_edge.set(u,INVALID);
jacint@211
    76
	  min_weight.set(u,0);
jacint@211
    77
	  reach.set(u,false);
jacint@211
    78
	}
jacint@211
    79
jacint@173
    80
jacint@173
    81
	typename Graph::NodeMap<bool> scanned(G, false);
jacint@173
    82
	typename Graph::NodeMap<int> heap_map(G,-1);
jacint@173
    83
	
jacint@173
    84
	Heap heap(heap_map);
jacint@173
    85
jacint@173
    86
	heap.push(r,0); 
jacint@211
    87
	reach.set(r, true);
jacint@173
    88
jacint@173
    89
	while ( !heap.empty() ) {
jacint@173
    90
jacint@211
    91
	  Node v=heap.top(); 
jacint@173
    92
	  min_weight.set(v, heap.get(v));
jacint@173
    93
	  heap.pop();
jacint@173
    94
	  scanned.set(v,true);
jacint@173
    95
jacint@173
    96
	  OutEdgeIt e;
jacint@211
    97
	  for( G.first(e,v); G.valid(e); G.next(e)) {
alpar@986
    98
	    Node w=G.target(e); 
jacint@173
    99
	    
jacint@211
   100
	    if ( !scanned[w] ) {
jacint@211
   101
	      if ( !reach[w] ) {
jacint@211
   102
		reach.set(w,true);
jacint@211
   103
		heap.push(w, edge_weight[e]); 
jacint@173
   104
		tree_edge.set(w,e);
jacint@211
   105
	      } else if ( edge_weight[e] < heap.get(w) ) {
jacint@173
   106
		tree_edge.set(w,e);
jacint@211
   107
		heap.decrease(w, edge_weight[e]); 
jacint@173
   108
	      }
jacint@173
   109
	    }
jacint@173
   110
	  }
jacint@173
   111
jacint@173
   112
	  InEdgeIt f;
jacint@211
   113
	  for( G.first(f,v); G.valid(f); G.next(f)) {
alpar@986
   114
	    Node w=G.source(f); 
jacint@173
   115
	    
jacint@211
   116
	    if ( !scanned[w] ) {
jacint@211
   117
	      if ( !reach[w] ) {
jacint@211
   118
		reach.set(w,true);
jacint@211
   119
		heap.push(w, edge_weight[f]); 
jacint@173
   120
		tree_edge.set(w,f);
jacint@211
   121
	      } else if ( edge_weight[f] < heap.get(w) ) {
jacint@173
   122
		tree_edge.set(w,f);
jacint@211
   123
		heap.decrease(w, edge_weight[f]); 
jacint@173
   124
	      }
jacint@173
   125
	    }
jacint@173
   126
	  }
jacint@173
   127
	}
jacint@173
   128
      } 
jacint@173
   129
 
jacint@173
   130
jacint@173
   131
      T weight() {
jacint@173
   132
	T w=0;
jacint@211
   133
	NodeIt u;
jacint@211
   134
	for ( G.first(u) ; G.valid(u) ; G.next(u) ) w+=min_weight[u];
jacint@173
   135
	return w;
jacint@173
   136
      }
jacint@173
   137
     
jacint@173
   138
jacint@211
   139
      Edge tree(Node v) {
jacint@211
   140
	return tree_edge[v];
jacint@173
   141
      } 
jacint@173
   142
jacint@173
   143
jacint@173
   144
      bool conn() {
jacint@173
   145
	bool c=true;
jacint@211
   146
	NodeIt u;
jacint@211
   147
	for ( G.first(u) ; G.valid(u) ; G.next(u) ) 
jacint@211
   148
	  if ( !reached[u] ) { 
jacint@173
   149
	    c=false;
jacint@173
   150
	    break;
jacint@173
   151
	  }
jacint@173
   152
	return c;
jacint@173
   153
      }
jacint@173
   154
jacint@173
   155
jacint@211
   156
      bool reached(Node v) {
jacint@211
   157
	return reached[v];
jacint@173
   158
      }
jacint@173
   159
jacint@173
   160
jacint@211
   161
      Node root() {
jacint@173
   162
	return r;
jacint@173
   163
      }
jacint@173
   164
jacint@173
   165
    };
jacint@173
   166
jacint@173
   167
}
jacint@173
   168
jacint@173
   169
#endif
jacint@173
   170
jacint@173
   171