普里姆算法思想:(数据结构书)
从连通网络 N = { V, E }中的某一顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中。
以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把该边加入到生成树的边集TE中,把它的顶点加入到集合U中。
如此重复执行,直到网络中的所有顶点都加入到生成树顶点集合U中为止
也就是:
1.清空生成树,任取一个顶点加入生成树
2.在那些一个端点在生成树里,另一个端点不在生成树里的边中,选取一条权最小的边,将它和另一个端点加进生成树
3.重复步骤2,直到所有的顶点都进入了生成树为止,此时的生成树就是最小生成树
代码实现:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include<bits/stdc++.h>
#define INF 10000 using namespace std; const int N = 6; bool visit[N]; int dist[N] = { 0, }; ///表示各个点与生成树的最短路径 int graph[N][N] = { {INF, 7, 4, INF, INF, INF}, ///INF代表两点之间不可达 { 7, INF, 6, 2, INF, 4}, { 4, 6, INF, INF, 9, 8}, {INF, 2, INF, INF, INF, 7}, {INF, INF, 9, INF, INF, 1}, {INF, 4, 8, 7, 1, INF} }; int prim( int cur) { int index = cur; int sum = 0; cout << index << " "; memset(visit, false, sizeof(visit)); visit[cur] = true; for( int i = 0; i < N; i++) dist[i] = graph[cur][i]; ///初始化,每个与a邻接的点的距离存入dist for( int i = 1; i < N; i++) { int minor = INF; for( int j = 0; j < N; j++) { if(!visit[j] && dist[j] < minor) ///找到未访问的点中,距离当前最小生成树距离最小的点 { minor = dist[j]; index = j; } } visit[index] = true; cout << index << " "; sum += minor; for( int j = 0; j < N; j++) { if(!visit[j] && dist[j] > graph[index][j]) ///执行更新,如果 生成树 距离当前点的距离更近,就更新dist { dist[j] = graph[index][j]; } } } cout << endl; return sum; ///返回最小生成树的总路径值 } int main() { cout << prim( 0) << endl; ///从顶点a开始 return 0; } |