| 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)) {
 | 
| jacint@211 |     98 | 	    Node w=G.head(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)) {
 | 
| jacint@211 |    114 | 	    Node w=G.tail(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 | 
 |