/*用普里姆算法求最小生成树*/
#include <iostream>
using namespace std;
/*邻接矩阵的类型定义*/
#define MAX 10000000
#define MAX_VERTEX_NUM 20
typedef struct
{
char vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息
int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组充当矩阵,来存储顶点边的信息
int vexnum,edgenum;//顶点树和边数
}MGraph;
/*构造无向联通网的邻接矩阵*/
void CreateUDG_AM(MGraph &G,int n,int e)
{
G.vexnum=n;
G.edgenum=e;
int i,j,k;
for(i=0;i<n;i++)
cin>>G.vexs[i];//输入顶点信息
for(i=0;i<n;i++)
for(j=0;j<n;j++)
G.edges[i][j]=MAX;//将矩阵初始化为无穷大
for(k=0;k<e;k++)
{
cin>>i>>j;
cin>>G.edges[i][j];//这里只用输入对称的边就行,也就是输入下矩阵或是上矩阵
G.edges[j][i]=G.edges[i][j];
}
}
//辅助数组定义
typedef struct
{
char adjvex;
int lowcost;
}CostOfVU;
CostOfVU closedge[MAX_VERTEX_NUM];//该一维数组用来存储V-U和U之间的权值
int LocateVex(MGraph &G,char x)
{//确定顶点在一维数组中的位置
int i=0;
while(G.vexs[i]!=x && i<G.vexnum)
i++;
return i;
}
int MinEdge(CostOfVU *p,MGraph &G)
{//求U和V-U之间最小的权值,在V-U中的顶点的位置
int i;
int k=0;
for(i=0;i<G.vexnum;i++)
{
while(p[k].lowcost==0)
k++;//找到权值不为0的顶点
while((p[i].lowcost==0||i==k)&&i<G.vexnum)
i++;//找到k后第一个不为0的顶点
if((p[k].lowcost>p[i].lowcost)&&i<G.vexnum)
k=i;//比较权值
}
return k;
}
//调用上面的函数求最小生成树
void MiniSpanTree_Prim(MGraph &G,char u)
{
int i,j,k;
k=LocateVex(G,u);//确定u在连通图中的位置
for(i=0;i<G.vexnum;i++)
{//将V-U中的顶点到U中的顶点的权值都存储到closedge数组中
closedge[i].adjvex=G.vexs[k];
closedge[i].lowcost=G.edges[k][i];
}
closedge[k].lowcost=0;//该句表示将顶点u纳入到U中
for(i=1;i<G.vexnum;i++)
{
k=MinEdge(closedge,G);//寻找closedge数组中权值最小的顶点,并返回其位置。
cout<<closedge[k].adjvex<<"-"<<G.vexs[k]<<":"<<closedge[k].lowcost<<endl;//输出找到的边和权值
closedge[k].lowcost=0;//将第k个顶点并入U集中
for(j=0;j<G.vexnum;j++)
{//更新V-U到U之间的权值
if(G.edges[k][j]<closedge[j].lowcost)
{
closedge[j].adjvex=G.vexs[k];
closedge[j].lowcost=G.edges[k][j];
}
}
}
}
void main()
{
freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
MGraph G;
CreateUDG_AM(G,6,9);
MiniSpanTree_Prim(G,'0');
}