有向图最小生成树——最小树形图(朱…

对于有向图的最小生成树 , 也叫做最小树形图 。 最小树形图的第一个算法是1965年朱永津和刘振宏提出的复杂度为O(VE)的算法。 值得我们骄傲啊 。
下面来分享这个算法 。
1、求最小树形图之前一定要确定根 , 确定根之后再去验证是否存在树形图(这个很简单 , 就是从根节点能不能到其他点) 。

2、如果存在树形图 , 然后再消掉自环 , 因为对于最小树形图 , 是肯定不能存在自环的(还有原因后面会讲到) 。

3、前面是两个预处理 。 求每个节点入边的最小值(除根节点) , 然后再把(求每个节点入边的最小值的边)这些边单独拿出来 , 看它们之间是否存在环(这就是为什么要先消除自环), 如果不存在那么这就是最小树形图。

4、如果存在环 , 那么就开始消环 , 用一个结点来取代这个环中的所有点 , 然后再把其放到原图中 , 构成新的图 , 并且图中的边的权值要改变为:grap[i].c(原边的权值) -= min_cost[v](该边出点的最小入边值); , 然后再回到步骤3 , 重复操作 , 就能得到最小树形图。

下面是最小树形图的构造图示:




有向图最小生成树鈥斺斪钚∈餍瓮迹ㄖ炝跛惴ǎ



















代码:
邻接表法:

#include
#include
#include
#include
using namespace std;

const int MAXN = 1000;
struct node
{
      int from , to , dist;
      node(int from , int to , int dist)  //  c++中的类应用
      {
            this->from = from ;
            this->to = to;
            this->dist = dist;
      }
};

vectoredge;
int pre[MAXN] , min_dist[MAXN] ;  //分别记录每个节点入边的最小值和入边另外一个点
int n , m , root , ret;

void init()
{
      edge.clear();
      root = 1;
}

bool solve()
{
      ret = 0;  //  记录最小总权值
      while(1)
      {
            int i;
            for(i = 1; i <= n; i++)  min_dist[i] = 1000000;
            for(i = 0 ; i < edge.size(); i++)  //  求每个节点的最小入边 ,
            {
                  int u = edge[i].from , v = edge[i].to;
                  if(edge[i].dist < min_dist[v] && v != u)  //  把自环除开
                  {
                        min_dist[v] = edge[i].dist;
                        //cout<<min_dist[v
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值