[图论总结] 最小生成树问题!

最小生成树

在这里插入图片描述
(图片来源于:Acwing算法基础课)

最小生成树问题是什么?

官方解释:

给定一张边带权的无向图G=(V, E),
其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。
由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树

样例解释:

地图上有n个城市,需要在城市时间铺设公路,问铺设公路的总长度的最小值之和


在这里我们一般只求无向图的最小生成树

由于堆优化的prim不常用 我这里只罗列出Prim和Kruskal的算法思路和代码


稠密图和稀疏图的简单划分:

  • 看边和点的平方是否接近,接近那么是稠密图

Prim朴素版(O n^2) 非常像dijkstra 稠密图

算法思路:

  • 初始化dist[] = 0x3f
  • 迭代n次 每次找到集合外距离最近的点(集合是已被用来更新的点的集合)
  • 用该点来更新其他点到集合的距离

代码:

初始化dist
memset(dist, 0x3f, sizeof dist);

int res = 0;
for (int i = 0; i < n; i ++ )
迭代n次 dij是迭代n-1次因为 他在第一次选定了一个点
{
    int t = -1;
    
    for (int j = 1; j <= n; j ++ )
        if (!st[j] && (t == -1 || dist[t] > dist[j]))找到不在集合中 且没有更新过的点
            t = j;

    if (i && dist[t] == INF) 如果不是第一个点 并且到每个点都是正无穷
    return INF;这里用来判断是否存在最小生成树

    if (i) 只要不是第一个点
    res += dist[t]; 那么就加上每一个边权 因为n个点的边数是n-1 所以正好去掉第一个点
  
    st[t] = true;
    for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
}

Krukal 稀疏图 O mlogn

算法思路:

  • 先将所有边 按权重从小到大排序
  • 枚举每条边 a,b,w
  • 如果a和b两个集合不连通,那么就将这条边加到集合
  • ( 最开始每个点 都是单独的一个集合 )

存边方式

struct Edge
{
    int a, b, w;
    bool operator< (const Edge &W)const
    {
        return w < W.w;
    }
重载运算符 就相当于sort(a,a+n,cmp)中的cmp 也可以自己定义cmp
}edges[M];

使用结构体存边的原因:
因为只用到边,而且需要给边排序所以就不用复杂的邻接表

代码实现:

int kruskal()
{
    sort(edges, edges + m);

    for (int i = 1; i <= n; i ++ ) p[i] = i;

    int res = 0, cnt = 0;

    for (int i = 0; i < m; i ++ )
    {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;

        a = find(a), b = find(b);
        如果a 和 b不在一个集合
        if (a != b)
        {
            p[a] = b;
            res += w;
            cnt ++ ;
        }
    }

    也就是存在 自己指向自己的边
    if (cnt < n - 1) 
    这个cnt到底是什么
    return INF;
    return res;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值