最小生成树Minimum Spanning Tree

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

  树: 无回路

     |V|个顶点,一定有|V|-1条边

  生成树: 包含全部顶点

             |V|-1 条边都在图里

  边权重和最小

最小生成树存在<--->图联通

数据结构学习笔记05图(最小生成树 Prim Kruskal)向生成树中任加一条边都一定构成回路

贪心算法

  “贪”:每一步都要最好的

  “好”:权重最小的边

  需要约束:

    ①只能用图里有的边

    ②只能正好用掉|V|-1条边

    ③不能有回路

 

Prim算法— 让一棵小树长大

数据结构学习笔记05图(最小生成树 Prim Kruskal)

步骤  
1 任意选取v1为顶点开始,并将v1收录进MST
2 v1有三条边,选取最短边(v1,v4)为1,并将v4收录进MST
3 MST={v1,v4}的边中在选取最小的(v1,v2)为2,将v2收录进MST
4 MST={v1,v4,v2},选(v4,v3)为2,将v3收录进MST
5 不能选(v4,v2)3,会构成回路。所以接着选(v4,v7)4,将v7收录进MST
6 选(v7,v6)为1,将v6收录进MST
7 (v7,v5)6,将v7收录进MST

 

 

 

 

 

 

 

 

 

数据结构学习笔记05图(最小生成树 Prim Kruskal)

T = O(|V|^2) ---稠密图合算

 1 /* 邻接矩阵存储 - Prim最小生成树算法 */
 2  
 3 Vertex FindMinDist( MGraph Graph, WeightType dist[] )
 4 { /* 返回未被收录顶点中dist最小者 */
 5     Vertex MinV, V;
 6     WeightType MinDist = INFINITY;
 7  
 8     for (V=0; V<Graph->Nv; V++) {
 9         if ( dist[V]!=0 && dist[V]<MinDist) {
10             /* 若V未被收录,且dist[V]更小 */
11             MinDist = dist[V]; /* 更新最小距离 */
12             MinV = V; /* 更新对应顶点 */
13         }
14     }
15     if (MinDist < INFINITY) /* 若找到最小dist */
16         return MinV; /* 返回对应的顶点下标 */
17     else return ERROR;  /* 若这样的顶点不存在,返回-1作为标记 */
18 }
19 
20 /* 将最小生成树保存为邻接表存储的图MST,返回最小权重和 */ 
21 int Prim( MGraph Graph, LGraph MST )
22 { 
23     WeightType dist[MaxVertexNum], TotalWeight;
24     Vertex parent[MaxVertexNum], V, W;
25     int VCount;
26     Edge E;
27      
28     /* 初始化。默认初始点下标是0 */
29        for (V=0; V<Graph->Nv; V++) {
30         /* 这里假设若V到W没有直接的边,则Graph->G[V][W]定义为INFINITY */
31            dist[V] = Graph->G[0][V];
32            parent[V] = 0; /* 暂且定义所有顶点的父结点都是初始点0 */ 
33     }
34     TotalWeight = 0; /* 初始化权重和     */
35     VCount = 0;      /* 初始化收录的顶点数 */
36     /* 创建包含所有顶点但没有边的图。注意用邻接表版本 */
37     MST = CreateGraph(Graph->Nv);
38     E = (Edge)malloc( sizeof(struct ENode) ); /* 建立空的边结点 */
39             
40     /* 将初始点0收录进MST */
41     dist[0] = 0;
42     VCount ++;
43     parent[0] = -1; /* 当前树根是0 */
44  
45     while (1) {
46         V = FindMinDist( Graph, dist );
47         /* V = 未被收录顶点中dist最小者 */
48         if ( V==ERROR ) /* 若这样的V不存在 */
49             break;   /* 算法结束 */
50              
51         /* 将V及相应的边<parent[V], V>收录进MST */
52         E->V1 = parent[V];
53         E->V2 = V;
54         E->Weight = dist[V];
55         InsertEdge( MST, E );
56         TotalWeight += dist[V];
57         dist[V] = 0;
58         VCount++;
59          
60         for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
61             if ( dist[W]!=0 && Graph->G[V][W]<INFINITY ) {
62             /* 若W是V的邻接点并且未被收录 */
63                 if ( Graph->G[V][W] < dist[W] ) {
64                 /* 若收录V使得dist[W]变小 */
65                     dist[W] = Graph->G[V][W]; /* 更新dist[W] */
66                     parent[W] = V; /* 更新树 */
67                 }
68             }
69     } /* while结束*/
70     if ( VCount < Graph->Nv ) /* MST中收的顶点不到|V|个 */
71        TotalWeight = ERROR;
72     return TotalWeight;   /* 算法执行完毕,返回最小权重和或错误标记 */
73 }
View Code

相关文章:

  • 2021-06-23
  • 2021-11-22
  • 2021-10-20
  • 2021-11-12
  • 2021-12-09
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-18
  • 2022-01-24
  • 2021-12-28
  • 2022-01-08
  • 2021-04-11
相关资源
相似解决方案