#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include"ALGraph.h"
#define INFINITY 4270000
typedef int VRType;
typedef struct min
{ /* 记录从顶点集U到V-U的代价最小的边的辅助数组定义 */
VertexType adjvex;
VRType lowcost;
}minside[MAX_VERTEX_NUM];
int GetWeight(ALGraph G,VertexType a,VertexType b );//获取权值
int minimum(minside SZ,ALGraph G); // 求SZ.lowcost的最小正值,并返回其在SZ中的序号
void MiniSpanTree_PRIM(ALGraph G,VertexType u);// 用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边
int main()
{
ALGraph g;
int n;
CreateGraphF (g); // 利用数据文件创建无向图
Display(g); // 输出无向图
scanf("%d",&n);
printf("用普里姆算法从g的第%d个顶点出发输出最小生成树的各条边:\n",n);
MiniSpanTree_PRIM(g,g.vertices [n].data); // Prim算法从第1个顶点构造最小生成树
}
int GetWeight(ALGraph G,VertexType a,VertexType b )//获取权值
{ int pa,pb;
pa=LocateVex(G,a);
pb=LocateVex(G,b);
ArcNode* p;
p=G.vertices[pa].firstarc;
if(pa == pb)
return 0;
while(p!=NULL)
{ if( p->data.adjvex == pb)
return p->data.info;
else
p=p->nextarc;
}
return INFINITY;
}
int minimum(minside SZ,ALGraph G)
{ /* 求SZ.lowcost的最小正值,并返回其在SZ中的序号 */
int i=0,j,k,min;
while(!SZ[i].lowcost)
i++;
min=SZ[i].lowcost; /* 第一个不为0的值 */
k=i;
for(j=i+1;j<G.vexnum;j++)
if(SZ[j].lowcost>0 && min>SZ[j].lowcost) /* 找到新的大于0的最小值 */
{
min=SZ[j].lowcost;
k=j;
}
return k;
}
void MiniSpanTree_PRIM(ALGraph G,VertexType u)
{
// 用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边
/********** Begin **********/
int k;
minside sz;
k=LocateVex(G,u);
for(int i=0;i<G.vexnum;i++)
{
strcpy(sz[i].adjvex,u);
sz[i].lowcost=GetWeight(G,G.vertices[k].data ,G.vertices[i].data);
}
sz[k].lowcost=0;
printf("最小代价生成树的各条边为:\n");
for(int i=1;i<G.vexnum;i++)
{
k=minimum(sz,G);
printf("边(%s,%s),权值为%d\n", sz[k].adjvex,G.vertices [k].data,sz[k].lowcost);
sz[k].lowcost=0;
for(int j=0;j<G.vexnum;j++)
{
int min=GetWeight(G,G.vertices [k].data ,G.vertices[j].data);
if( min!=INFINITY && min!=0 && min<sz[j].lowcost)
{
strcpy(sz[j].adjvex,G.vertices[k].data );
sz[j].lowcost=GetWeight(G,G.vertices[k].data ,G.vertices[j].data);
}
}
}
/********** End **********/
}