Prim 算法

问题描述:求最小生成树(MST)。

算法步骤:

本质是贪心。

①   初始集合MST为空.

②   由图中任一顶点N开始,将N加入 MST。

③   找出外部顶点中与当前MST顶点相距最短的顶点M和边(M,N),加入MST

④   重复②直至全部节点都加入MST为止

算法依据:

关于最小生成树:最小生成树是总边权值最小的生成树,一个连通图的生成树是包含所有顶点的极小连通子图,极小连通子图是包含所有顶点的无环连通子图。

最小生成树的性质:任取子集U ⊂ V且U≠∅,若u∈U,v∈V-U,且(u,v)在所有U到V-U的边中具有最小权值(又称为轻边),则必有一棵最小生成树包含(u,v)。用反证法易证。

算法实现:

View Code
 1 int dis[101][101];
 2 bool flag[101];
 3 int nv, ne;//number of vertexs and edges
 4 class Edge
 5 {
 6 public:
 7     int v1, v2, len;
 8     Edge(int a, int b) : v1(a), v2(b){len = dis[a][b];}
 9     bool operator <(const Edge& e) const{return len > e.len;}
10 };
11 priority_queue<Edge> edge;//use priority_queue as the container
12 
13 int prim()
14 {
15     int MstEdgeNum = 0;//Minium-cost Spanning Tree
16     int totalCost = 0;
17     flag[1] = true;//choose 1 as the first vertex
18     for (int i = 1; i <= nv; i++)
19         if (dis[1][i] < INF)
20             edge.push(Edge(1, i));
21     while(!edge.empty())
22     {
23         Edge e = edge.top();
24         edge.pop();
25         if (flag[e.v1] && !flag[e.v2])
26         {
27             flag[e.v2] = true;
28             totalCost += e.len;
29             DmstEdgeNum++;
30             if (DmstEdgeNum == nv-1)
31                 return totalCost;
32             for (int i = 1; i <= nv; i++)
33                 if (dis[e.v2][i] < INF)
34                     edge.push(Edge(e.v2, i));
35         }
36     }
37     return -1;
38 }

算法复杂度:O(n^2)

posted on 2012-12-12 12:27  澄哥  阅读(196)  评论(0)    收藏  举报

导航