_min_spanning.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:4k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _min_spanning.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. /*******************************************************************************
  12.  *
  13.  *                          MIN_SPANNING_TREE
  14.  *
  15.  *      Kruskal's Algorithm for computing a minimum spanning tree
  16.  *
  17.  * In order to avoid sorting the entire edge set we proceed as follows:
  18.  * We first run Kruskal's Algorithm with the 3*n cheapest edges of the graph. 
  19.  * In general, this gives already a good approximation. Then we collect all 
  20.  * edges still connecting different components and run the algorithm for them.
  21.  * 
  22.  *       worst case running time:  m * log n
  23.  * ????? expected running time:    m * alpha(n) + n * log n  ?????
  24.  *
  25.  * S.N. (1992)
  26.  *
  27.  ******************************************************************************/
  28. #include <LEDA/graph_alg.h>
  29. #include <LEDA/node_partition.h>
  30. #include <LEDA/node_pq.h>
  31. #include <LEDA/basic_alg.h>
  32. static const edge_array<num_type>* edge_cost;
  33. static int CMP_EDGES(const edge& e1, const edge& e2) 
  34. { return compare((*edge_cost)[e1],(*edge_cost)[e2]); }
  35. static void KRUSKAL(list<edge>& L, node_partition& P, list<edge>& T)
  36.   L.sort(CMP_EDGES);
  37.   edge e;
  38.   forall(e,L)
  39.   { node v = source(e);
  40.     node w = target(e);
  41.     if (! P.same_block(v,w))
  42.     { T.append(e);
  43.       P.union_blocks(v,w);
  44.      }
  45.    }
  46.  }
  47. list<edge> MIN_SPANNING_TREE(const graph& G, const edge_array<num_type>& cost)
  48.   list<edge> T;
  49.   list<edge> L;
  50.   node_partition P(G);
  51.   edge e;
  52.   edge_cost = &cost;
  53.   int n = G.number_of_nodes();
  54.   int m = G.number_of_edges();
  55. /* Compute 3n-th biggest edge cost x by SELECT (from basic_alg.h)
  56.  * and sort all edges with cost smaller than x in a list L
  57.  */
  58.   if (m > 3*n)
  59.    { num_type* c = new num_type[m];
  60.      num_type* p = c;
  61.      forall_edges(e,G) *p++ = cost[e];
  62.      num_type x = SELECT(c,p-1,3*n);
  63.      delete c;
  64.      forall_edges(e,G) 
  65.         if (cost[e] < x) L.append(e);
  66.     }
  67.   else
  68.     L = G.all_edges();
  69.   KRUSKAL(L,P,T);
  70. // collect and sort edges still connecting different trees into L
  71. // and run the algorithm on L
  72.   L.clear();
  73.   forall_edges(e,G) 
  74.      if (!P.same_block(source(e),target(e))) L.append(e);
  75.   KRUSKAL(L,P,T);
  76.   return T;
  77. }
  78. /*******************************************************************************
  79.  *
  80.  *                          MIN_SPANNING_TREE1
  81.  *
  82.  * priority-queue-based algorithm  for undirected graphs
  83.  *
  84.  * for details see Mehlhorn Vol. II, Section IV.8, Theorem 2
  85.  *
  86.  * Running time with Fibonnaci heap:  O(m + n * log n)   
  87.  *                                    ( m * decrease_p + n * del_min)
  88.  *
  89.  * S.N. (1992)
  90.  *
  91.  ******************************************************************************/
  92. list<edge> MIN_SPANNING_TREE1(const graph& G, const edge_array<num_type>& cost)
  93. {
  94.   // computes a minimum spanning tree of the underlying undirected graph
  95.   list<edge> result;
  96.   node_pq<num_type> PQ(G); 
  97.   node_array<num_type> dist(G,MAXINT); 
  98.                                  // dist[v] = current distance value of v
  99.                                  // MAXINT: no edge adjacent to v visited
  100.                                  //-MAXINT: v already in a tree
  101.   node_array<edge> T(G,nil);      // T[v] = e with cost[e] = dist[v]
  102.   node v;
  103.   forall_nodes(v,G)  PQ.insert(v,MAXINT);
  104.   while (! PQ.empty())
  105.   { 
  106.     node u = PQ.del_min();
  107.     if (dist[u] != MAXINT) result.append(T[u]);
  108.     dist[u] = -MAXINT;
  109.     edge e;
  110.     forall_inout_edges(e,u)
  111.     { v = G.opposite(u,e);
  112.       num_type c = cost[e];
  113.       if (c < dist[v])
  114.       { PQ.decrease_p(v,c);
  115.         dist[v] = c;
  116.         T[v] = e;
  117.        }
  118.      }
  119.    }
  120.  return result;
  121. }