您的位置:首页 > 其它

普里姆(Prim)算法求解最小生成树

2013-03-05 18:40 447 查看
我们把构造连通网的最小代价生成树称为最小生成树。

Prim算法:

假设N=(P,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0} (u0∈V),TE={}开始。重复执行下述操作:在所有的u∈V-U的边(u,v)∈E中找一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直到U=V为止。此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树。



代码如下:
#include<iostream>
#include<queue>
using namespace std;

typedef char VertexType;//顶点数据类型
typedef int EdgeType;//边上的权值数据类型
const int MAXVEX = 100;//最大顶点数
const int INFINITY = 65535;//代表无穷大
typedef struct
{
VertexType vexs[MAXVEX];//顶点表
EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵,可看作边表
int numVertexes, numEdges;//图中当前的顶点数和边数
}MGraph;

void CreateMGraph(MGraph *G)
{
int i,j,k,w;
printf("请输入顶点数和边数:\n");
scanf("%d,%d",&G->numVertexes,&G->numEdges);
for(i=0; i<G->numVertexes; i++)
{
fflush(stdin);
printf("请输入顶点%d的值:\n",i);
scanf("%c",&G->vexs[i]);
}
for(i=0; i<G->numVertexes; i++)//初始化邻接表
{
for(j=0; j<G->numVertexes; j++)
{
if(i == j)
G->arc[i][j] = 0;
else
G->arc[i][j] = INFINITY;
}
}
for(k=0; k<G->numEdges; k++)//在邻接表中写入具体数据
{
printf("请输入边(vi,vj)上的下标i,j和权w:\n");
scanf("%d,%d,%d",&i,&j,&w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];//因为是无向图,矩阵对称
}
}

/************************************************************************/
/* Prim算法生成最小生成树 */
/************************************************************************/
void MiniSpanTree_Prim(MGraph G)
{
int min,i,j,k;
int adjvex[MAXVEX];//保存相关顶点下标
int lowcost[MAXVEX];//保存相关顶点边的权值
lowcost[0] = 0;//初始化第一个权值为0,即v0加入生成树。lowcost的值为0,在这里就是此下标的顶点已经加入生成树
adjvex[0] = 0;//初始化第一个顶点下标为0
for (i=1; i<G.numVertexes; i++)//循环除下标为0外的全部顶点
{
lowcost[i] = G.arc[0][i];//将v0顶点与之有边的权值存入数组
adjvex[i] = 0;//初始化都为v0的下标
}

for (i=1; i<G.numVertexes; i++)
{
min = INFINITY;//初始化最小权值为无穷大
j=1;
k=0;
while (j < G.numVertexes)
{
if (0 != lowcost[j] && lowcost[j]<min)
{
min = lowcost[j];
k = j;
}
j++;
}
printf("(%d,%d)",adjvex[k],k);
lowcost[k] = 0;
for (j=1; j<G.numVertexes; j++)
{
if (0 != lowcost[j] && G.arc[k][j] <lowcost[j])
{
lowcost[j] = G.arc[k][j];
adjvex[j] = k;
}
}
}
}

int main()
{
MGraph G;
CreateMGraph(&G);
for(int i=0; i<G.numVertexes; i++)
{
for(int j=0; j<G.numVertexes; j++)
{
printf("%d ",G.arc[i][j]);
}
printf("\n");
}
MiniSpanTree_Prim(G);
cout<<endl;
system("pause");
return 0;
}

结果:



算法时间复杂度O(n^2)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: