kruskal算法

kruskal算法求最小生成树:

(1)将所有边按照权重进行排序;

(2)依次选取每条边,判断该边两端顶点是否联通,若不联通,则将该边加入集合中。

(3)如果最后加入了n-1条边,则说明存在最小生成树,否则没有。

 

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


using namespace std;

const int N = 100010, M = 200010;

struct Edge
{
    int a, b, w;
    
    bool operator <(const Edge &W)const 
    {
        return w < W.w;    
    }
}edges[M];


int n, m, cnt, p[N];

int find(int x)
{
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}

int kruskal()
{
    int res = 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)
        {
            // 若a,b不联通,需要联通a,b
            p[a] = b;
            res += w;
            cnt++; //表示多连上了一条边
        }
    }
    // cout << cnt << endl;
    // n个顶点的最小生成树只有n-1条边
    if(cnt == n-1) return res;
    else return -1;
}

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;
        edges[i] = {a,b,w};
    }
    
    sort(edges, edges+m);
    
    int res = kruskal();
    if(res == -1) puts("impossible");
    else cout << res << endl;
    return 0;
}

代码来自ACWing(https://www.acwing.com/)。

 

posted @ 2022-07-13 11:19  krystalZ2021  阅读(67)  评论(0)    收藏  举报