prim算法求最小生成树

----天道酬勤

算法描述:

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:V new = {x},其中x为集合V中的任一节点(起始点),E new = {},为空;
3).重复下列操作,直到V new = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合V new中的元素,而v不在V new 集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合V new中,将<u, v>边加入集合E new中;
4).输出:使用集合V new和E new来描述所得到的 最小生成树

源自百度百科

实现:

typedef enum{
dg,dn,udg,udn
}graphkind;
typedef struct
{
  char data;
  int sign;    //访问标志
}vertextype;
typedef struct
{
vertextype vexs[max];
int arcs[max][max];
int vexnum,arcnum;
graphkind kind;

}graph;

void prim(graph *s)
{
   int data[max];  //存储访问的顶点
   int k=0; 
   int i,j;
   int a,b;      //存储最短路径的始末点
   int temp;
   int min,flag;    
   for(i=0;i<s->vexnum;i++)   //把顶点标记为未访问 
   {
     s->vexs[i].sign=0;  
   }
   data[k]=0;
   s->vexs[0].sign=1;
   while(k<s->vexnum-1)
   {
      min=0;
      flag=0;
    for(i=0;i<=k;i++)
      {
    temp=data[i];
    for(j=0;j<s->vexnum;j++)
    {
    if(!s->vexs[j].sign&&s->arcs[temp][j]!=0)
    {
    if(0==flag)          //初始化min
    {
    min=s->arcs[temp][j];
    a=temp;
    b=j;
    flag=1;
}
if(min>s->arcs[temp][j])
{
min=s->arcs[temp][j];
a=temp;
b=j;
}
}
}
   }
            data[++k]=b;        //加入已访问
   s->vexs[b].sign=1;
   cout<<s->vexs[a].data<<'-'<<s->vexs[b].data<<':'<<min<<endl;
 }

}


猜你喜欢

转载自blog.csdn.net/fight_snail/article/details/80632593
今日推荐