最小生成树

一颗带权无向图的生成树的代价是该生成树中所有边的代价之和,最小代价生成树就是一颗代价最小的生成树,构建无向图的最小生成树就是采用贪心算法,不过对于最小生成树问题,需满足以下约束条件:

  • 只能使用图中的边
  • 只能使用恰好n-1条边
  • 不能使用产生环路的边
    Kruskal算法通过每次向当前最小代价生成树T中加入一条边的方法构成最终的最小生成树T,算法按照边的代价非递减的顺序选取,并加入T中,如果所选取的边与T中的边不形成环路,则这条边加入到T中,由于图G是连通的,且具有n个顶点,所以最终恰好选取n-1条边加入到T中。
    如图所示:
    这里写图片描述
权值结果
初始化
(0,5)10加入树
(2,3)12加入
(1,6)14加入
(1,2)16加入
(3,6)18丢弃
(3,4)22加入
(4,6)24丢弃
(4,5)25加入
(0,1)28不再考虑

为了实现Kruskal算法,必须找出最小代价的边并将其从E中删除,如果把E中的边按权值进行排序,保存为一个顺序表,就可以有效的完成上述两个操作,但实际上,只要能够快速地找到下一条边最小代价的边,就没有要对E中的边进行排序,显然最小堆非常适合这个任务,因为最小堆可以在O(loge)时间内找出并删除下一条最小权值的边,而构造最小堆本身的时间复杂性为O(e).
伪代码实现:

//最小生成树算法
void create minTree()
{
   T={};//最小生成树的集合
   //T的边数需小于n-1,却无向图的边不能为空
   while(T.edgesCount<n-1&&E.edgesCount>0)
   {
      minHeap(v,w,E);//从无向图E集合选择最小代价的边
      delete(v,w,E);//删除该边
      //如果新加入边不构成环,则加入,否则丢弃
      if(!isCycle(v,w,T))
      {
         add(v,w,T)
      }
      else
      {
         discard(v,w)
      }
   }
   //检查最小生成树的边数是否满足约束条件
   if(T.egdescount!=n-1)
   {
      printf("No spanning tree\n");
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值