Prim算法
2013-11-27 05:07
225 查看
一、Prim 算法的思想:
普里姆算法的基本思想是以顶点为主导地位:从起始顶点出发,通过选择当前可用的最小权值边依次把其他顶点加入到生成树当中来。
设连通无向网为G(V, E),在普里姆算法中,将顶点集合V分成两个子集合T和T':
T:当前生成树顶点集合,
T':不属于当前生成树的顶点集合。
很显然有:T∪T'= V。
普里姆算法的具体过程为:
1) 从连通无向网G中选择一个起始顶点u0,首先将它加入到集合T中;然后选择与u0关联的、具有最小权值的边 (u0, v),将顶点v加入到顶点集合T中。
2) 以后每一步从一个顶点(设为u)在T中,而另一个顶点(设为v)在T'中的各条边中选择权值最小的边(u, v),把顶点v加入到集合T中。如此继续下去,直到网络中的所有顶点都加入到生成树顶点集合T中为止。
二、Prim算法实现
假设采用邻接矩阵来存储图。在普里姆算法运算过程当中,需要知道以下两类信息:① 集合T'内各顶点距离T内各顶点权值最小的边的权值;② 集合T'内各顶点距离T内哪个顶点最近(即边的权值最小)。为了存储和表示这两类信息,必须定义2个辅助数组:
1) lowcost[ ]: 存放顶点集合T'内各顶点到顶点集合T内各顶点权值最小的边的权值。
2) nearvex[ ]: 记录顶点集合T'内各顶点距离顶点集合T内哪个顶点最近;当nearvex[i]为-1
时,表示顶点i 属于集合T。
注意,lowcost 数组和nearvex数组可以合二为一,
普里姆算法的基本思想是以顶点为主导地位:从起始顶点出发,通过选择当前可用的最小权值边依次把其他顶点加入到生成树当中来。
设连通无向网为G(V, E),在普里姆算法中,将顶点集合V分成两个子集合T和T':
T:当前生成树顶点集合,
T':不属于当前生成树的顶点集合。
很显然有:T∪T'= V。
普里姆算法的具体过程为:
1) 从连通无向网G中选择一个起始顶点u0,首先将它加入到集合T中;然后选择与u0关联的、具有最小权值的边 (u0, v),将顶点v加入到顶点集合T中。
2) 以后每一步从一个顶点(设为u)在T中,而另一个顶点(设为v)在T'中的各条边中选择权值最小的边(u, v),把顶点v加入到集合T中。如此继续下去,直到网络中的所有顶点都加入到生成树顶点集合T中为止。
二、Prim算法实现
假设采用邻接矩阵来存储图。在普里姆算法运算过程当中,需要知道以下两类信息:① 集合T'内各顶点距离T内各顶点权值最小的边的权值;② 集合T'内各顶点距离T内哪个顶点最近(即边的权值最小)。为了存储和表示这两类信息,必须定义2个辅助数组:
1) lowcost[ ]: 存放顶点集合T'内各顶点到顶点集合T内各顶点权值最小的边的权值。
2) nearvex[ ]: 记录顶点集合T'内各顶点距离顶点集合T内哪个顶点最近;当nearvex[i]为-1
时,表示顶点i 属于集合T。
注意,lowcost 数组和nearvex数组可以合二为一,
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int MAXN = 21; const int INF = 10000010; int Edge[MAXN][MAXN]; int lowcost[MAXN]; int nearvex[MAXN]; int n, m; void Prime(int u) { int i, j; for (i = 1; i <= n; ++i) { lowcost[i] = Edge[u][i]; nearvex[i] = u; } nearvex[u] = -1; int sum = 0; for(i = 1; i <= n; ++i) { int min = INF; int v = -1; for (j = 1; j <= n; ++j) { if (nearvex[j] != -1 && lowcost[j] < min) { v = j; min = lowcost[j]; } } if (v != -1) { cout<<nearvex[v]<<" -> "<<v<<": "<<lowcost[v]<<endl; nearvex[v] = -1; sum += lowcost[v]; for (j = 1; j <= n; ++j) { if (nearvex[j] != -1 && lowcost[j] > Edge[v][j]) { nearvex[j] = v; lowcost[j] = Edge[v][j]; } } } } cout<<"The weight of MST is: "<<sum<<endl; } int main() { int i,j; int u,v,w; cin>>n>>m; while( m-- ) { cin>>u>>v>>w; Edge[u][v] = Edge[v][u] = w; } for(i = 1; i <= n; ++i) { for(j = 1; j <= n; ++j) { if(i == j) Edge[i][j] = 0; else if(Edge[i][j] == 0) Edge[i][j] = INF; } } Prime( 1 ); system("pause"); return 0; }
相关文章推荐
- C++/CLI程序启动时_CrtIsValidHeapPointer(pUserData)错误
- Recursion 字符串的全排列 String Permutation @CareerCup
- jqurey 中dialog未定义问题
- Pipeline组Alpha版本发布说明
- Pipeline组测试说明
- C++之I/O流
- webapi调用post时自动匹配参数
- 黑马程序员_JavaBean_内省
- C++ 输入输出
- 老师这份职业
- 老师这份职业
- windows server 2012之搭建DHCP服务器
- poj 2421 Constructing Roads (Kruskal)
- msys 编译 openresty 记录(失败)
- 删除数据
- 更新和删除数据
- jdk环境变量配置
- 插入检索出的数据——即从一个表插入到另外一张表
- 鼠标捕获(setCapture,releaseCapture)的学习
- 搞ACM的你们伤不起