您的位置:首页 > 其它

最小生成树之Prim算法详解

2018-02-09 10:12 393 查看

最小生成树之Prim算法

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。
算法思想:
1) .输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,在顶点集合V中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

4).输出:使用集合Vnew和Enew来描述所得到的最小生成树

图例说明:
      原图:              
                             
                

           
       第一步:找一个A点,找与A点距离最短的点C,<A,C>为1,连接
               


        第二步:找与A,C距离最近的点且连接没有回路的点,为F,<C,F>为4,连接
   
              


          第三步:找与A,C,F距离最近的点且连接没有回路的点,为D,<F,D>为2,连接
                 

                  
           第四步:找与A,C,F,D距离最近的点且连接没有回路的点,为B,<C,B>为5,连接
                       


          第五步:找与A,B,C,F距离最近的点且连接没有回路的点,为E,<B,E>为3,连接
            


时间复杂度:Prim的时间复杂度为O(n*n),与网中的边数无关,因此适用于求变稠密的网的最小生成树
代码如下:int Prim(int k)
{int v[1005];//保存点
int b[1005]://保存最短路径
memset(v,0,sizeof(v));
v[k]=1;
for(int i=1;i<=n;i++)
b[i]=a[k][i];
b[k]=0;
int sum=0,l;
for(int i=1;i<n;i++)
{
int max=0x3f3f;
for(int j=1;j<=n;j++)
{
if(!v[j]&&b[j]<max) //求当前最短路径
{
l=j; //求当前最短路径的点
max=b[j];
}
}
if(!v[l])
sum+=b[l]; //求出当前最短路径后加在一起
v[l]=1; //保存当前的点
for(int j=1;j<=n;j++)
{
if(!v[j]&&b[j]>a[l][j]) //更新
b[j]=a[l][j];
}
}
return sum;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: