最小生成树-Prim算法

假设要在n个城市之间建立通讯联络网,不同城市间建立通讯设施的代价不同,如何在最节省经费的前提下建造这个通讯网。

即找权值之和最小的极小连通子网,问题转换为在连通网中找一颗生成树,最小生成树。

输入:创建图。

输出:组成最小生成树的所有边。

运行结果:

Prim算法:设U代表已并入最小生成树的顶点的集合,最初任选一点放入U,之后找到U到其补集最小边。将对应新顶点并入。共N-1轮即可。

1、从顶点u0开始,令U={u0},初始化u0到其余各顶点距离。

2、{找最小的边输出,并入新结点,赋0+更新表使U到非U距离更小}。

如此重复n-1次。

算法实现:

邻接矩阵存储:

构造表对应的数组,每个元素对应一个顶点,元素取值是U中到当前点最近的点和边的权值,顶点被并入U后权值置0。

typedef double VRType;

struct{ //对应数组 每个元素一个顶点
   VertexType adjvex; //U中到当前点最近的点名称
   VRType lowcost; //U中点到当前点的最小代价
}closedge[MVNUM];

用Prim算法从v出发求网G最小生成树 输出各边.

void MiniSpanTree_Prim(MGraph G,VertexType v){
   //用Prim算法从v出发求网G最小生成树 输出各边
   int k=LocateVex(G,v),i,j;
   closedge[k].lowcost=0; //将v并入U 赋0
   for(j=0;j<G.vexnum;j++){ //据v更新数组元素代价
       if(j!=k) {
           closedge[j].adjvex=v;
           closedge[j].lowcost=G.arcs[k][j].adj;
       }
   }
   for(i=1;i<G.vexnum;i++){//共n-1轮 每轮找最小边输出 赋0更新
       k=minimum(G);
       printf("%c->%c\n",closedge[k].adjvex,G.vexs[k]); //输出v->k
       closedge[k].lowcost=0; //将k号结点并入U 赋0
       for(j=0;j<G.vexnum;j++)//据k号结点更新数组元素代价
          if(G.arcs[k][j].adj<closedge[j].lowcost){
              closedge[j].adjvex=G.vexs[k];
              closedge[j].lowcost=G.arcs[k][j].adj;
          }
   }
}

代价非零的元素中找最小元素 返下标.

int minimum(MGraph G){
   //代价非零的元素中找最小元素 返下标
   int i,k,flag=0;
   double min;
   for(i=0;i<G.vexnum;i++){
      if(closedge[i].lowcost){
          if(!flag){ //初始化最小值
	      min=closedge[i].lowcost;
	      k=i; //保存下标
	      flag=1; //是否初始化标记
	  }
          if(min>closedge[i].lowcost){
              min=closedge[i].lowcost;
              k=i;
          }
       }
   }
   return k;
}

邻接表存储:

void MiniSpanTree_Prim(ALGraph G,VertexType v){
   //用Prim算法从v出发求网G最小生成树 输出各边
   int k=LocateVex(G,v),i,j;
   closedge[k].lowcost=0; //将v并入U 赋0
   for(j=0;j<G.vexnum;j++){
       if(j!=k) {
           closedge[j].adjvex=v;
           closedge[j].lowcost=INFINITY;
       }
   }
   ArcNode *p=G.vertices[k].firstarc;
   while(p){
       closedge[p->adjvex].lowcost=p->adj;
       p=p->nextarc;
   }
   for(i=1;i<G.vexnum;i++){ //共n-1轮 每轮找最小边输出 赋0更新
       k=minimum(G);
       printf("%c->%c\n",closedge[k].adjvex,G.vertices[k].data); //输出v->k
       closedge[k].lowcost=0; //将k号结点并入U 赋0
       ArcNode *p=G.vertices[k].firstarc;//据k号结点更新数组元素代价
       while(p){
           if(p->adj<closedge[p->adjvex].lowcost){
	       closedge[p->adjvex].adjvex=G.vertices[k].data;
               closedge[p->adjvex].lowcost=p->adj;
	   }
	   p=p->nextarc;
       }
   }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值