AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

详解与促背模板 -- 算法基础课 -- 搜索与图论(三):最小树Kruskal

作者: 作者的头像   MW10 ,  2025-01-11 08:27:33 ,  所有人可见 ,  阅读 2


0


#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = 200010, INF = 0x3f3f3f3f;

// 只需要存储边
int n, m;
struct Edge
{
    int a, b, w;

    bool operator< (const Edge &W)const
    {
        return w < W.w;
    }
}edges[M];

// 并查集操作:查看是否在一个集合
int p[N];
int find(int x)
{
    // 并查集数组模拟:为根则返回,否则往根回溯
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

// Kruskal输出最小生成树权重和
int kruskal()
{
    // Kruskal: 边排序,从小到大遍历边

    // 边排序
    sort(edges, edges + m);

    // 从小到大遍历边: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);
        // 仅在不连通加入边
        if (a != b)
        {
            p[b] = a;
            res += w;
            // 判断图是否连通 cnt
            cnt ++ ;
        }
    }

    if (cnt < n - 1) return INF;
    return res;
}

int main()
{
    // 输入有向图
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++ )
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        edges[i] = {a, b, w};
    }

    int t = kruskal();

    if (t == INF) puts("impossible");
    else printf("%d\n", t);

    return 0;
}

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息