Prim算法求最小生成树
来源:互联网 发布:数据统计分析 需要 编辑:程序博客网 时间:2024/04/30 08:04
//核心 Prim算法求最小生成树/* 编一C程序,它能根据输入数据构造带权无向图G, 并输出G的最小生成树。 图的输入形式为n V0 Vi0 w0 V1 Vi1 w1 V2 Vi2 w2 ...Vi Vin wn -1 -1 -1(-1,-1,-1为输入结束标记,其余的值都>=0且<n),它们都是整数,且100>n>0。*/#include <stdio.h>#define infinity 1000000 //常数infinity为无穷大#define max_vertexes 100 //常数max_vertexes为图最大节点数//typedef int Graph[max_vertexes][max_vertexes];void prim(int G[][max_vertexes],int vcount,int father[]);int juZhen(int g[][max_vertexes]);void main(){ int g[max_vertexes][max_vertexes];int vcount=0,father[max_vertexes]; vcount=juZhen(g); //初始化矩阵printf("该图的最小生成树为\n"); prim(g,vcount,father); }/* lowcost: 记录权值的 used[]: //记录每个顶点是否被并入:默认值为0;当并入后修改对应值为1 father[]: closeset[]: */void prim(int G[][max_vertexes],int vcount,int father[]) { int i,j,k,m=0; int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];int min; //初始化------------------------------------ for (i=0;i<vcount;i++) { used[i]=0;closeset[i]=0;father[i]=-1; } //------------------------------------------------ used[0]=1; //把第0个顶点归入集合u中for(i=0;i<vcount;i++){ lowcost[i]=G[0][i]; //把各顶点到顶点0的权值保存在lowcost[i]中} //---------------------------------------------------- for (i=1;i<vcount;i++) //循环次数:n个顶点,进行n-1次即可 ( u={v0}, 剩下的顶点{v1,.......} 开始生成最小生成树) { //求最小值min=infinity;for(m=0;m<vcount;m++){ if(used[m]==0 && lowcost[m]<min) { min=lowcost[m]; j=m; }}father[j]=closeset[j]; //记录j的前领结点 used[j]=1; //把顶点j并入u中 for (k=0;k<vcount;k++) //新顶点并入u后重新选择最小边(针对lowcost[k]的修改){ if (!used[k]&&(G[j][k]<lowcost[k])) { lowcost[k]=G[j][k]; closeset[k]=j; }} } //自己加的:最小生成树的生成 for(m=0;m<vcount;m++) { if(father[m]!=-1) { printf("v%d-v%d\t",father[m],m); } }}int juZhen(int g[][max_vertexes]){ int vCount=0,i=0,j=0,w=0,m=0,n=0;printf("功能:依输入数据构造带权无向图G,并输出G的最小生成树\n\n"); printf("请输入图的顶点数,范围在1-%d\n",max_vertexes); //输入顶点个数scanf("%d",&vCount);while(vCount<0 || vCount>max_vertexes){ printf("顶点个数输入有误,请重新输入"); scanf("%d",&vCount);} printf("则顶点的范围在0-%d\n",vCount-1); for(m=0;m<vCount;m++) //图的矩阵初始化{ for(n=0;n<vCount;n++) { g[m][n]=infinity; //默认权值为无穷大 }} printf("请输入图中边所连顶点i与j,及边的权值,以 -1 -1 -1为结束标志\n"); //图的矩阵 scanf("%d %d %d",&i,&j,&w);while(i!=-1 && j!=-1 && w!=-1) { //对顶点i j范围限制if(i<0 ||i>=vCount || j<0 ||j>=vCount){ printf("顶点输入有误,请重新输入\n");continue;}else{ g[i][j]=w; g[j][i]=w;} scanf("%d %d %d",&i,&j,&w);}return vCount;}