算法导论-最小生成树-prim算法

来源:互联网 发布:蓝桥杯c语言试题2017 编辑:程序博客网 时间:2024/06/05 21:14

关于最小生成树的prim算法原理这里不多做介绍了。与kruskal算法相比,都是利用了贪心策略来求最小生成树,不同的是:

Kruskal算法中,集合A是一个森林;选择最小的权值边加入到森林。

Prim算法中,集合A则是一棵树;每次加入到A中的安全边永远是连接A和A之外某个结点的边中权重最小的边。相当于树的生长。

下面是Prim算法的代码,里面有详细的注释:

#include<stdio.h>#include<stdlib.h>#define n 9//图中点的个数#define max n*n//图中的边的个数#define inf 9999//标示无穷大struct edge{    int u;//起点    int v;//终点    int value;//边的权值}e[max];int p[n];//p[i]用于记录依次加入最小生成树的顶点/*-----------------------------prim算法-----------------------------*/int prim(int en[][n],int v){    int i,j,k,kk=0,min=inf,count=0;//min标示无穷大,count用于记录最小生成树各边的权值    int lowcost[n];//lowcost[i]用于记录顶点i到最小生成树t中的顶点的最短路径权值    int intree[n];//intree[i]用于记录顶点i是否在最小生成树中,1:在;0:不在。    for(i=0;i<n;i++)//初始化    {        if(en[i][v]==inf)//路径不可达            lowcost[i]=inf;        else //有可达路径            lowcost[i]=en[i][v];        intree[i]=0;        p[i]=-1;    }    intree[v]=1;//标记顶点v为最小生成树中的顶点    p[0]=v;    for(i=0;i<n-1;i++)//选择其余的n-1个顶点    {        min=inf;        for(j=0;j<n;j++)//选出到最小生成树t中顶点最短的顶点k        {            if(intree[j]==0 && lowcost[j]<min)            {                min=lowcost[j];                k=j;            }        }        count=count+min;//记录权值        intree[k]=1;        v=k;        p[++kk]=k;//记录依次加入最小生成树的顶点        /**        **开始时,lowcost[]是记录其他点到v(这时v是根结点)的距离        **当新加入一个结点k后,令v=k,在剩下的未加入结点中寻找,如果v到某点j的距离小于lowcost[j],更新lowcost[j]        **这也就是prim算法的贪心策略        */        for(j=0;j<n;j++)        {            if(intree[j]==0 && en[v][j]!=0 && en[v][j]<lowcost[j])                lowcost[j]=en[v][j];        }    }    return(count);}/*-----------------------------主函数-------------------------------*/int main(){    int i,sum=0;    char vex;    //en表示各个点之间的连接情况,为inf表示无边,其他值表示边的权值看 :)    int en[n][n]={{0,4,inf,inf,inf,inf,inf,8,inf},            {4,0,8,inf,inf,inf,inf,11,inf},            {inf,8,0,7,inf,4,inf,inf,2},            {inf,inf,7,0,9,14,inf,inf,inf},            {inf,inf,inf,9,0,10,inf,inf,inf},            {inf,inf,4,14,10,0,2,inf,inf},            {inf,inf,inf,inf,inf,2,0,1,6},            {8,11,inf,inf,inf,inf,1,0,7},            {inf,inf,2,inf,inf,inf,6,7,0}};    printf("输入最小生成树的构造开始顶点(a,b,c,d,e,f,g,h,i):\n");    scanf("%c",&vex);    sum=prim(en,vex-'a');    printf("最小生成树的代价为:%d\n",sum);    printf("构造最小生成树依次加入树的顶点为:\n");    for(i=0;i<n-1;i++)        if(p[i]!=-1)            printf("%c -> ",p[i]+'a');        printf("%c\n",p[i]+'a');    return 0;}


0 0
原创粉丝点击