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)

浙公网安备 33010602011771号