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;}

原创粉丝点击