最小生成树——普里姆(Prim)算法
2017-02-17 22:25
218 查看
Prim算法的基本思想是以顶点为主导地位;从起始顶点出发,通过选择当前可用的最小权值的边把其他顶点加入到生成树中来。设连通无向网为G(V,E),在普里姆算法中,将顶点集合V分成两个子集T和T'.
(1)T:当前生成树顶点集合。
(2)T':不属于当前生成树的顶点集合
具体实现过程如下:(1)从连通无向网中选择一个起始顶点u0,首先将它加入到集合T中;然后选择与u0关联的,具有最小权值的边(u0,v),将顶点v加入到集合T中。
(2)以后每一步从一个顶点(设为u)在T中,而另一个顶点(设为v)在T'中的各条边中选择权值最小边(u,v),把顶点v加入到集合T中。如此继续,直到网络中的所有顶点都加入到生成树集合T中为止。
例题:利用prim()算法求下图中的最小生成树,并输出依次选择的各条边及最终求得的最小生成树的权值。
分析说明:
(1)lowcost[]:存放顶点集合T'内到顶点集合T内各顶点权值最小的边的权值
(2)nearvex[]:记录顶点集合T'内各顶点距离顶点集合T内哪个顶点最近;当nearvex[i]==-1时,表示顶点i属于顶点T.
prim()算法的简化版(只是为了单纯的求最小生成树而已),代码如下
(1)T:当前生成树顶点集合。
(2)T':不属于当前生成树的顶点集合
具体实现过程如下:(1)从连通无向网中选择一个起始顶点u0,首先将它加入到集合T中;然后选择与u0关联的,具有最小权值的边(u0,v),将顶点v加入到集合T中。
(2)以后每一步从一个顶点(设为u)在T中,而另一个顶点(设为v)在T'中的各条边中选择权值最小边(u,v),把顶点v加入到集合T中。如此继续,直到网络中的所有顶点都加入到生成树集合T中为止。
例题:利用prim()算法求下图中的最小生成树,并输出依次选择的各条边及最终求得的最小生成树的权值。
分析说明:
(1)lowcost[]:存放顶点集合T'内到顶点集合T内各顶点权值最小的边的权值
(2)nearvex[]:记录顶点集合T'内各顶点距离顶点集合T内哪个顶点最近;当nearvex[i]==-1时,表示顶点i属于顶点T.
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define maxint 0x3f3f3f #define MAXN 110 int n,m; int map[MAXN][MAXN]; int lowcost[MAXN]; int nearvex[MAXN]; void prim(int u0) { int i,j,min; int sumweight=0; for(i=1;i<=n;i++) { lowcost[i]=map[u0][i]; nearvex[i]=u0; } nearvex[u0]=-1; for(i=1;i<n;i++) { min=maxint; int v=-1; for(j=1;j<=n;j++) if(nearvex[j]!=-1&&lowcost[j]<min)///在没有加入集合T的各点中选取距离集合T最近的顶点 { v=j; min=lowcost[j]; } if(v!=-1)///v==-1表示没有找到权值最小的边 { printf("%d %d %d\n",nearvex[v],v,lowcost[v]); nearvex[v]=-1; sumweight+=lowcost[v]; for(j=1;j<=n;j++) if(nearvex[j]!=-1&&map[v][j]<lowcost[j])///更新lowcost的权值 { lowcost[j]=map[v][j]; nearvex[j]=v;///j距离集合T中的最近顶点改变 } } } printf("weight of MST is %d\n",sumweight); } int main() { int i,j; int u,v,w; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,maxint,sizeof(map)); for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); map[u][v]=w; map[v][u]=w; } prim(1); } return 0; }
prim()算法的简化版(只是为了单纯的求最小生成树而已),代码如下
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define MAXN 30 #define maxint 0x3f3f3f3f int map[MAXN][MAXN]; int n,m; int visited[MAXN]; int lowcost[MAXN]; int prim() { int i,j; int min,pos,sumweight=0; memset(visited,0,sizeof(visited)); visited[1]=1; pos=1; for(i=1;i<=n;i++) if(i!=pos) lowcost[i]=map[pos][i]; for(i=1;i<n;i++) { min=maxint; for(j=1;j<=n;j++) if(visited[j]==0&&lowcost[j]<min)///在还没有访问的顶点中选择距离集合T最近的一个 { min=lowcost[j]; pos=j; } sumweight+=min; visited[pos]=1; for(j=1;j<=n;j++) if(visited[j]==0&&map[pos][j]<lowcost[j])///没有被访问的。更新lowcost的值 lowcost[j]=map[pos][j]; } return sumweight; } int main() { int i,j; int u,v,w; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,maxint,sizeof(map)); for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); map[u][v]=w; map[v][u]=w; } int ans=prim(); cout<<ans<<endl; } }
相关文章推荐
- 最小生成树-普里姆Prim()算法
- 求最小生成树,普里姆(Prim)算法
- 图解最小生成树 - 普里姆(Prim)算法
- 普里姆(Prim)算法求解最小生成树
- 最小生成树(MST)----普里姆(Prim)算法与克鲁斯卡尔(Kruskal)算法
- 图论中最小生成树算法-Prim(普里姆)算法、kruskal(克鲁斯卡尔避圈法)算法、破圈算法
- 最小生成树之普里姆(Prim)算法
- C++ 最小生成树之Prim(普里姆)算法
- 数据结构之---C语言实现最小生成树之prim(普里姆)算法
- 最小生成树的普里姆(Prim)算法
- 最小生成树prim(普里姆)算法
- 求最小生成树,普里姆(Prim)算法
- 最小生成树之Prim(普里姆)算法
- 最小生成树 Prim(普里姆)算法和Kruskal(克鲁斯特尔)算法
- Prim(普里姆)算法求最小生成树
- 算法:图解最小生成树之普里姆(Prim)算法
- 最小生成树之Prim(普里姆)算法
- 数据结构之---C语言实现最小生成树之prim(普里姆)算法
- 求最小生成树,普里姆(Prim)算法
- 算法:图解最小生成树之普里姆(Prim)算法