最小生成树算法

最小生成树算法

最小生成树——克鲁斯卡尔算法:给定一个有权无向图,求其最小生成树。克鲁斯卡尔算法是最常用的解决方法

题目描述

给定一些边的信息,每条边有一个权值,求由这些边组成的最小生成树的权值和。

答案

使用克鲁斯卡尔算法,先将所有的边按权值从小到大排序,然后对于每条边,判断这两个点是否在同一个连通分量中,若不在则将这条边加入最小生成树,并将这两个点所在的连通分量合并。

代码

以下是使用C++实现克鲁斯卡尔(Kruskal)算法求最小生成树的代码:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

// 定义边的结构体
struct Edge {
    int from, to, weight;
};

const int MAXN = 100; // 最大顶点数
int parent[MAXN]; // 父节点数组,用于并查集
vector<Edge> edges; // 存储边的数组

// 并查集查找祖先
int find(int x) {
    if (parent[x] != x) {
        parent[x] = find(parent[x]);
    }
    return parent[x];
}

// 克鲁斯卡尔算法求最小生成树
void kruskal(int n) {
    sort(edges.begin(), edges.end(), [](Edge a, Edge b) { // 将边按权值从小到大排序
        return a.weight < b.weight;
    });

    for (int i = 0; i < n; i++) { // 初始化并查集
        parent[i] = i;
    }

    for (auto edge : edges) {
        int root1 = find(edge.from); // 查找两个顶点所在树的根
        int root2 = find(edge.to);

        if (root1 == root2) { // 如果已经在同一棵树,则跳过
            continue;
        }

        parent[root1] = root2; // 否则将两棵树合并
        cout << "Edge from " << edge.from << " to " << edge.to << " with weight " << edge.weight << endl;
    }
}

int main() {
    int n; // 顶点数
    int m; // 边数

    cin >> n >> m;

    for (int i = 0; i < m; i++) { // 输入图的边
        int from, to, weight;
        cin >> from >> to >> weight;
        edges.push_back({from, to, weight});
    }

    kruskal(n);

    return 0;
}

在以上代码中,我们首先定义了一个边的结构体Edge,然后按照边的权值从小到大对边进行排序,接着使用并查集来判断两个顶点是否在同一棵树中,若不在,则将它们合并,并输出这个边。最后,我们在main函数中读入输入数据,然后调用kruskal函数求最小生成树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值