#include <stdio.h> #define INFINITE 9999 #define MAX_VEX_NUM 40 void prim (int g[][MAX_VEX_NUM],int n) { int lowcost[MAX_VEX_NUM],closest[MAX_VEX_NUM]; int i,j,k,min; for (i=2;i<=n;i++) { lowcost[i]=g[1][i];//初始化,表示第i个点到U的最小权值 //将U看成一个点,例如U={V1,V2},则 //lowcost[3]表示第3个点到V1,V2两条 //中的最小权值那条变得权值,当lowcost[i] //=0时,表示将i点加入了U中 closest[i]=1;//closest[i]=j,表示j属于U,i不属于U的边(i,j) } lowcost[1]=0;//表示顶点1加入U集合 for (i=2;i<=n;i++)//形成n-1条边的生成树 { min=INFINITE; k=0; for (j=2;j<=n;j++)//寻找满足边的一个顶点在U,另一个顶点在V的最小边 if ((lowcost[j]<min)&&(lowcost[j]!=0/*顶点j不属于U*/)) { min=lowcost[j]; k=j; } printf("(%d,%d)%d/t",closest[k],k/**最小权值变得两个顶点*/,min); lowcost[k]=0;//将顶点k加入U for (j=2;j<=n;j++)//修改顶点集合U到其他顶点的最小权值,即U中各点到V中一点各边中的最小权值 if(g[k][j]<lowcost[j]) { lowcost[j]=g[k][j]; closest[j]=k; } printf("/n"); } } int CreateG(int g[][MAX_VEX_NUM]) { int n,e,i,j,k,v1,v2,weight; printf("输入顶点个数,边的条数:"); scanf("%d%d",&n,&e); for (i=1;i<=n;i++) for (j=1;j<=n;j++) g[i][j]=INFINITE;//初始化邻接矩阵,设全部元素为INFINITE for (k=1;k<=e;k++) { printf("输入第%d条边的起点,终点,权值:",k); scanf("%d%d%d",&v1,&v2,&weight); g[v1][v2]=g[v2][v1]=weight; } return (n); } void OutputG(int g[][MAX_VEX_NUM],int n) { int i,j; for (i=0;i<=n;i++) printf("%d/t",i); for (i=1;i<=n;i++) { printf("/n%d/t",i); for(j=1;j<=n;j++) printf((g[i][j]==INFINITE)?"/t":"%d/t",g[i][j]); } printf("/n"); } int main() { int g[MAX_VEX_NUM][MAX_VEX_NUM],n; n=CreateG(g); printf("输入无向图矩阵:/n"); OutputG(g,n); printf("最小生成树:/n"); prim(g,n); return 0; }