普里姆算法(Prim)

  普里姆(Prim)算法是一种构造性算法。假设G=(V,E)是一个具有n个顶点的带权连通图,T=(U,TE)G的最小生成树,其中UT的顶点集,TET的边集,则从v0开始构造最小生成树T的步骤如下:
  1) 初始化={v0},将v0到其他顶点的所有边作为候选边。
  2) 重复以下操作n1次,使得其他n1个顶点被加入到U中:
  2.1) 从候选边中挑选权值最小的边输出,设该边在VU中的顶点是v, 将v加入到U中,删除和v关联的边;
  2.2) 考察当前VU中的所有顶点vi,修正候选边。若(v,vi)的权值小于原来和vi关联的候选边,则用(v,vi)取代后者作为候选边。
  为了便于在集合UVU之间选择权值最小的边,建立了两个数组vsetlowcostvset[i]=1表示顶点iU中,vset[i]=0表示顶点iVU中。lowcost数组存放VU顶点到U中顶点的最小值,即lowcost[i]表示VU中顶点iU中顶点的最短边的权值。
  初始时lowcost[i]=g.edges[v0][i],
  在扩充顶点v后,若vset[j]=1(表示为VU中顶点), 且 g.edges[v][j]<lowcost[j], 说明VU中的顶点jU中顶点v的边权值更短, 需修改为lowcost[j]=g.edges[v][j]
  普里姆算法如下:  

void prim(MGraph g,int v)
{
    int lowcost[MAXV],min,n=g.vexnum;
    int closest[MAXV],i,j,k;
    for (i=0;i<n;i++)           //给lowcost[]和closest[]置初值
    {   
        lowcost[i]=g.edges[v][i];
        closest[i]=v;
    }
    for (i=1;i<n;i++)           //找出n-1个顶点
    {   
        min=INF;
        for (j=0;j<n;j++)       //在(V-U)中找出离U最近的顶点k
            if (lowcost[j]!=0 && lowcost[j]<min) 
            {   
                min=lowcost[j];k=j;  
            }
        printf("  边(%d,%d)权为:%d\n",closest[k],k,min);
        lowcost[k]=0;           //标记k已经加入U
        for (j=0;j<n;j++)       //修改数组lowcost和closest
            if (g.edges[k][j]!=0 && g.edges[k][j]<lowcost[j]) 
            {   
                lowcost[j]=g.edges[k][j];closest[j]=k; 
            }
    }
}

  普里姆算法的时间复杂度为O(n2),适用于稠密图。

阅读更多
个人分类: C++ 算法 笔试
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭