#include <stdio.h>
#define MaxVertexNum 100
/* 最大顶点数设为100 */
#define MaxEdgeNum 100
/* 最大边数设为100 */
#define MaxCost 9999
/* 边的权值最大为9999 */
typedef char VertexType;
/* 顶点类型设为字符型 */
typedef int EdgeCost;
/* 边的权值设为整型 */
typedef struct
{ VertexType vexs[MaxVertexNum];
/* 存放顶点信息 */
EdgeCost edges[MaxVertexNum][MaxVertexNum];
/* 存放邻接关系 */
int n,e; /*顶点数和边数*/
}Mgraph;
typedef struct
{ int v1;
int v2;
EdgeCost cost;
}EdgeType;
void CreateMGraph(Mgraph *G)
{int i,j,k,w;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n") ;
scanf("%d,%d",&(G->n),&(G->e));
printf("请输入顶点信息:\n");
for(i=0;i<G->n;i++)
scanf("\n%c",&(G->vexs[i]));
for(i=0;i<G->n;i++)
for(j=0;j<G->n;j++)
G->edges[i][j]=MaxCost;
printf("请输入每条边对应的两个顶点的序号(输入格式为:i,j,w):\n");
for(k=0;k<G->e;k++)
{ scanf("%d,%d,%d",&i,&j,&w);
G->edges[i][j]=w;
G->edges[j][i]=w; }
}
void Sort(Mgraph *G, EdgeType e[],int *EdgeNum) /* 用Kruskal方法求最小生成树 */
{EdgeType e1;
int i,j,k,m;
int mincost;
m=-1;
for(i=0;i<G->n;i++)
for(j=i+1;j<G->n;j++)
if(G->edges[i][j]!=MaxCost)
{m++;
e[m].v1=i;
e[m].v2=j;
e[m].cost=G->edges[i][j];
} /*将边存入数组e中*/
for(i=0;i<m;i++)
{mincost=e[i].cost;
k=i;
for (j=i+1;j<=m;j++)
if(e[j].cost<mincost)
{mincost=e[j].cost;
k=j;
}
if (k!=i)
{e1=e[i];
e[i]=e[k];
e[k]=e1;
}
} /* 对m+1条边按权值排序 */
*EdgeNum=m+1;
}
int Find(int father[ ],int v)
/* 寻找顶点v所在树的根结点的编号 */
{ int t;
t=v;
while(father[t]>=0)
t=father[t];
return(t);
}
void Kruskal(EdgeType edges[],EdgeType T[],int m,int n)
/* 假定edges[]中的数据已按cost值由小到大排序 */
{ int father[MaxVertexNum];
int i,j,vf1,vf2;
for(i=0;i<n;i++) father[i]=-1;
i=0;j=0;
while (i<m && j<n-1)
{ vf1=Find(father,edges[i].v1);
vf2=Find(father,edges[i].v2);
if (vf1!=vf2)
/*vf1!=vf2表示两个顶点v1,v2不在一个连通分量上*/
{father[vf2]=vf1;
T[j]=edges[i];
j++;
}
i++;}
}
void main()
{Mgraph G;
EdgeType e[MaxEdgeNum],T[MaxEdgeNum];
int m,i;
CreateMGraph(&G);
Sort(&G,e,&m);
Kruskal(e,T,m,G.n);
for (i=0;i<G.n-1;i++)
printf("\n(%d,%d),%d",T[i].v1,T[i].v2,T[i].cost);
printf("\n");
}