乱炖 | 最小生成树、割点割边、最大二分匹配

图的最小生成树 Kruskal

思路:让边的总长度之和最短,首先选择最短的边,其次选择次短的……,直到选择了n-1条边为止。(注意选边不能造成回路)

难实现的是:判断两个顶点是否已经连通。(可以使用广搜或者深搜,但这样效率低)可以使用已经学习的并查集,把所有的顶点放到并查集中,判断两个顶点是否连通,只需判断两个顶点是否在同一个集合(即是否有共同的祖先)即可,这样时间复杂度为 O ( l o g N ) O(logN) O(logN)

Kruskal:首先按照边的权值进行从小到大排序,每次从剩余的边中选择权值较小且边的两个顶点不在同一个集合的边(就是不会产生回路的边),加入到生成树中,直到加入了n-1条边为止。
时间复杂度分析:对顶点进行快排的时间复杂度是 O ( N l o g N ) O(NlogN) O(NlogN),对边进行快排的时间复杂度是 O ( M l o g M ) O(MlogM) O(MlogM),在m条边中找到n-1条边的时间复杂度是 O ( M l o g N ) O(MlogN) O(MlogN),所以Kruskal算法的时间复杂度是 O ( M l o g M + M l o g N ) O(MlogM+MlogN) O(MlogM+MlogN),因为M通常比N大,所以最终时间复杂度是 O ( M l o g M ) O(MlogM) O(MlogM)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;

struct edge
{
   
    int u;
    int v;
    int w;
};

const int N = 110;
int n, m, a[N];
edge node[N];

void init()
{
   
    memset(a, 0, sizeof(a));
    for(int i = 1; i <= n; i++)
        a[i] = i
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值