用Prime算法实现最小生成树
假设要在 n 个城市之间建立通讯联络网,试用Prime算法构建连通n 个城市的通信网,使总的耗费最少。
要求:
1、用邻接矩阵cost存储。
2、用Prime 算法实现
/*
一、建立邻接矩阵
二、
1、初始化,选V为生成树的根
2、置0到其他各点的边权
3、选权值最小的边输出,并置标志-1
4、添加新的顶点W入生成树集合
5、修正lowcost和closest
6、重复3-5*/
#include<stdio.h>
#include<stdlib.h>
//------------------------------图的邻接矩阵存储表示----------------
#define MaxInt 32767 //表示极大值,无穷
#define MVNum 20 //最大顶点数
typedef char VerTexType; //假设顶点的数据类型为字符型
typedef int ArcType; //假设边的权值类型为整型
typedef struct
{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum, arcnum; //图的当前点数和边数
}AMGraph;
void CreateUDN(AMGraph *G);
int LocateVex(AMGraph G, char v,int vexnum);
void MinSpanTree_Prim(AMGraph G,VerTexType u);
int main()
{
char u;
AMGraph G;
CreateUDN(&G);
printf("\n-------------------------构造最小生成树--------------------------------\n");
printf("请输入跟结点:");
scanf("%c",&u);
MinSpanTree_Prim(G,u);
return 0;
}
//--------------采用邻接矩阵表示法,创建无向网G--------------------
void CreateUDN(AMGraph *G)
{
int i, k, j, v1, v2, w;
printf("请输入总的顶点数和总的边数:");
scanf("%d %d",&G->vexnum,&G->arcnum);
getchar(); //吸收回车符
printf("依次输入顶点名称:");
for (i=0; i<G->vexnum;i++) //依次输入顶点信息,即顶点名称
scanf("%c",&G->vexs[i]);
getchar(); //吸收回车符
for (i = 0; i <G->vexnum; i++) //初始化邻接矩阵,边的权值均设为最大值
for (j=0; j < G->vexnum; j++)
G->arcs[i][j] = MaxInt;
for (k=0; k<G->arcnum;k++) //构造邻接矩阵
{
printf("请输入第%d条边依附的两个顶点:", k+1);
scanf("%c %c",&v1,&v2);
getchar(); //吸收回车符
printf("请输入第%d条边依附的权值:",k+1);
scanf("%d",&w);
getchar(); //吸收回车符
i=LocateVex(*G,v1,G->vexnum);
j=LocateVex(*G,v2,G->vexnum); //确定v1,v2在G中的位置,即顶点数组的下标
G->arcs[i][j]=w;
G->arcs[j][i]=G->arcs[i][j]; //置<v1,v2>及其对称边的权值为w
}
return ;
}
//----------------------定位函数-----------------------
int LocateVex(AMGraph G, char v,int vexnum)
{
int i;
for (i=0; i<vexnum; i++)
{
if(G.vexs[i] ==v)
return i;
}
}
//---------------------建立最小生成树----------------
void MinSpanTree_Prim(AMGraph G,VerTexType u)
{//无向网G以邻接矩阵形式存储,从顶点U出发构造G的最小生成树T,输出T的各条边
int k,j,i;
k=LocateVex(G,u,G.vexnum); //k为顶点u的下标
int lowcost[G.vexnum]; //存放u到个点的权值
int closedge[G.vexnum]; //存放顶点
for(j=0;j<G.vexnum;j++)
{
if(j!=k)
lowcost[j]=G.arcs[k][j];
if(j==k)
lowcost[j]=-1;
closedge[j]=k; //初始化lowcost和closedge
}
for(i=1;i<G.vexnum;i++)
{
int Min;
Min=MaxInt;
for(j=0;j<G.vexnum;j++)
{
if(lowcost[j]!=-1&&lowcost[j]<Min) //查找与u邻接的权值最小的边,k存放另一个邻接顶点
{
Min=lowcost[j];
k=j;
}
}
printf("第%d条边:权值%4d 两个邻接顶点 %c 和 %c \n",i,Min,G.vexs[closedge[k]],G.vexs[k]);
lowcost[k]=-1;
for(j=0;j<G.vexnum;j++)
{
if(lowcost[j]!=-1&&G.arcs[k][j]<lowcost[j])
{
lowcost[j]=G.arcs[k][j];
closedge[j]=k;
}
}
}
return ;
}
测试用例:
输出结果: