#include "stdio.h"
#define MAX 10
#define INF 999
typedef struct Mgraph
{
int n; //图的顶点个数
int edge[MAX][MAX]; //图中边的权值
}Mgraph;
int lowest[MAX]; //lowest[vi]表示当前生成树这一整体到其余顶点的权值
int cloest[MAX]; //cloest[vi]保存v-s中点vi在s中最邻接顶点,v为总集合,s为目前的生成树
int vset[MAX]; //为标记数组,vset[vi]=1表示vi被并入最小生成树,否则没有
//v0为源点
//返回最小生成树的权值,并打印生成树中的边
int prime(int v0, Mgraph g)
{
int i, j;
//进行初始化
for(i=0; i<g.n; i++)
{
lowest[i] = g.edge[v0][i];
cloest[i] = v0;
vset[i] = 0;
}
vset[v0] = 1;
lowest[v0] = INF;
int sum = 0; //生成树的权值
int min, v;
for(i=0; i<g.n; i++)
{
min = INF;
/*用于选出候选边中的最小值*/
for(j=0; j<g.n; j++)
{ /*选出当前生成树到其余最短边中最短的一条*/
if(vset[j]==0 && lowest[j]<min)
{
min = lowest[j];
v = j;
}
}
vset[v] = 1; //此顶点被并入最短路径
printf("依次被选入的边为:\n");
if(i<g.n-1) //避免最后一条边被输出两次
{
printf("%d---%d\n", cloest[v], v);
sum += lowest[v]; //累加生成树的费用, 防止最后一条边的权值加两次
}
for(j=0; j<g.n; j++)
{
//判断顶点v加入是否会使通往顶点j的路径更短,如果出现,则改变原来的路径及长度
if(vset[j]==0 && g.edge[v][j]<lowest[j])
{
lowest[j] = g.edge[v][j]; //改变当前树到剩余顶点最短边的权值
cloest[j] = v; //改变到未并入最小生成数的最邻接顶点
}
}
}
return sum;
}
void init(Mgraph &g, int edge[][5], int n)
{
g.n = n;
int i, j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
g.edge[i][j] = edge[i][j];
}
int main(){
int n = 5;
int edge[][5]={
{1000, 5, 1, 2, 1000},
{5, 1000, 3, 1000, 4},
{1, 3, 1000, 6, 2},
{2, 1000, 6, 1000, 3},
{1000, 4, 2, 3, 1000}
};
Mgraph g;
init(g, edge, n);
int v0;
int i, j;
printf("图的矩阵为(1000表示不可直接到达):\n");
for(i=0; i<g.n; i++)
{
for(j=0; j<g.n; j++)
printf("%d\t", g.edge[i][j]);
printf("\n");
}
printf("请输入起始顶点(0~%d):", g.n-1);
scanf("%d", &v0);
int u = prime(v0, g);
printf("最小生成树的权值为:%d\n", u);
return 0;
}
最小生成树--prime
最新推荐文章于 2022-06-20 09:31:28 发布