Kruskal(克鲁斯卡尔)算法求最小生成树

217 阅读2分钟

什么是最小生成树?

1.关键词---生成树

1)没有环

2)包括图结构的所有点

说人话:有n个顶点的图结构,其边的个数为n - 1

2.关键词--最小

边的权值和最小的生成树

3.最小生成树场景

城市间连接光缆,铺设光缆的最小成本,每两个城市之间都要有光缆

如何构建最小生成树---什么是克鲁斯卡尔算法?

目标是达到权值和最小,克鲁斯卡尔是直接选择权值最小的边,prim是从顶点出发,间接找最小权值边,稀疏图用克鲁斯卡尔方法比较方便

算法步骤模板

1)将所有边按权重从小到大排序

2)枚举每一条边 a,b权重c

if a,b不相通 <1>

则将这条边加入集合

<1>:相通即图结构有环

题目链接:859. Kruskal算法求最小生成树 - AcWing题库

c++代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
int n,m,p[N];
struct Edge{
    int a,b,w;
}e[M];
bool cmp(Edge a,Edge b)
{
    return a.w < b.w;
}
int find(int x)//并查集模板
{
    if(p[x] != x)
    p[x] = find(p[x]);
    else
    return p[x];
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ )
    p[i] = i;
    for(int i = 0; i < m; i ++ )
    {
        int a,b,w;
        cin >> a >> b >> w;
        e[i] = {a,b,w};
    }
    sort(e,e + m,cmp);//<2>sort用法
    int res ,cnt;
    res = cnt = 0;
    for(int i = 0; i < m; i ++ )
    {
        int a = e[i].a,b = e[i].b,w = e[i].w;
        a = find(a),b = find(b);
        if(a != b)//如果这条边的加入不会产生环,即这两点不连通,则把这条边加入集合
        {
            p[a] = b;
            res += w;
            cnt ++;
        }
    }
    if(cnt < n-1)
    puts("impossible");
    else
    cout << res << endl;
    return 0;
}

<2>:sort函数:sort(begin,end,cmp)

该处用sort给结构体排序