在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树
Prim算法原理:
- 图的所有顶点集合为 V ;初始令集合 u={s},v=V−u ;
- 在两个集合 u,v 能够组成的边中,选择一条代价最小的边 (u0,v0) ,加入到最小生成树中,并把 v0 并入到集合u中。
- 重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止
#include<iostream>
#include<queue>
using namespace std;
#define INFINITY 65535
struct MGraph
{
char V[10];
int Edge[10][10];
int Vexnum;
int Edgenum;
};
void CreateGraph(MGraph *G) //初始化邻接矩阵
{
printf("请输入顶点数和边数:");
scanf("%d%d",&(G->Vexnum),&(G->Edgenum));
char c;
c=getchar();
int i,j;
for(i=0;i<G->Vexnum;i++)
for(j=0;j<G->Vexnum;j++)
G->Edge[i][j]=INFINITY;
printf("请输入顶点信息(char)型\n");
for(i=0;i<G->Vexnum;i++)
scanf("%c",&(G->V[i]));
c=getchar();
int w;
for(int k=0;k<G->Edgenum;k++)
{
printf("请输入(vi,vj)的下标i,j和权值w:");
scanf("%d%d%d",&i,&j,&w);
c=getchar();
G->Edge[i][j]=w;
G->Edge[j][i]=w;
}
}
int min(int a,int b)
{
return a<b?a:b;
}
int Prim(MGraph *G)
{
int mincost[10];
bool used[10];
for(int i=0;i<G->Vexnum;i++)
{
used[i]=false;
mincost[i]=INFINITY;
}
mincost[0]=0;
int res=0;
printf("依次生成的结点是:\n");
while(true)
{
int v=-1;
for(int u=0;u<G->Vexnum;u++)
{
if(!used[u]&&(v==-1||mincost[u]<mincost[v]))
v=u;
}
if(v==-1)
break;
used[v]=true;
printf("%c",G->V[v]);
res+=mincost[v];
for(int k=0;k<G->Vexnum;k++)
mincost[k]=min(mincost[k],G->Edge[v][k]);
}
printf("\n");
return res;
}
void main()
{
MGraph G;
CreateGraph(&G);
int res=Prim(&G);
printf("最小路径长度是:");
printf("%d\n",res);
}
原图:
运行: