您的位置:首页 > 其它

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数组可以合二为一,



#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: