(重要)最小生成树

概念

生成树

信息学里的树???
图论中一个V个点的图,取其中V-1条边,将他们连接起来,就是生成树。

最小生成树

生成树中边权总和最小的生成树,就是最小生成树。

图示

这里写图片描述

特点

1.环属性

一颗生成树上任意加一条边,必构成环。
再去掉环上最大权边,就得到了一颗可能更好的生成树。
这里写图片描述

2.剪切属性

生成树可以分成不相交两个集合(可以看作两颗子生成树),两颗子生成树之间有交叉边。最小交叉边一定要在最小生成树上。
这里写图片描述

3.其他

这里写图片描述

prim

算法

利用剪切属性,将点分为两个集合A,B。初始时A集合只有源点。
枚举每个交叉边,取最小边【i,j】,将边终点j加入集合A,用他更新到达B集合每条最短交叉边。

图示

这里写图片描述
这里写图片描述

代码

void prim(int s)
{
    memset(dis,10,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    vis[s]=1;
    for(int i=linkk[s];i;i=a[i].next)
      dis[a[i].y]=a[i].v;//初始化 
    for(int k=1;k<n;k++)
      {
        int minn=dis[0],c=0;
        for(int i=1;i<=n;i++)
          if (!vis[i]&&dis[i]<minn)
            {
                minn=dis[i];
                c=j;
            } 
        vis[c]=1;//加入集合A 
        ans+=minn; 
        for(int i=linkk[c];i;i=a[i].next)
          {
            int tn=a[i].y;
            if (!vis[tn]&&dis[tn]>a[i].v)
              dis[tn]=a[i].v;
          }//更新最短路。 
      }
}

kruscal

算法

由于要用到并查集,所以介绍下并查集http://blog.csdn.net/OIer00LCJ/article/details/78919112
kruscal是将所有边进行排序,因为最小边原则,将最小交叉边【i,j】入队,将【i,j】进行并集操作,使他们成为一个集合,也就是连了边;
进行n-1次合并后,就得到了一颗最小生成树。

图示

这里写图片描述
这里写图片描述

代码

int fa[maxn]={};
void init()//初始化 
{
    for(int i=1;i<=n;i++)
      fa[i]=i;
}
int getfather(int x)//找父结点+路径压缩 
{
    return (fa[x]==x) ? x:fa[x]=getfather(fa[x]);
}
void hebing(int x,int y)//合并 
{
    int fx=getfather(x),fy=getfather(y);
    fa[fx]=fy;
}
//并查集基本操作
void kruscal()
{
    int c=0;//计数器 
    int ans=0;
    sort(a+1,a+t+1);
    for(int i=1;i<=t;i++)
      {
        int x1=getfather(a[i].x);
        int y1=getfather(a[i].y);
        if (x1!=y1)
          {
            ans+=a[i].v;
            hebing(x1,y1);
            if(++c==n-1)
              break;
          }
      }
}

总结

prim算法
1.时间复杂度O(n^2);
2.可用堆优化O((E+V)*logV)
krusacl算法
1.时间复杂度O(E*logE+N*A*V)
2.适用于稀疏图。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值