Kruscal

本质上就是贪心,把边从小到大排,然后选边。按这个思路根据排法不同,就可以得出各种生成树。

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

using namespace std;

const int N = 100100, M = N * 2;

int h[N], ne[M], e[M], w[M], idx;
int n, m;
int p[N], cnt, ans;

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


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

void kruscal()
{
    sort(edges + 1, edges + 1 + m);
    
    int cnts = 0;
    for (int i = 1; i <= m; i ++ )
    {
        auto &e = edges[i];
        int pa = find(e.a), pb = find(e.b);
        if (pa != pb)
        {
            p[pb] = pa;
            ans += e.w;
            cnts ++ ;
        }
    }
    if (cnts != n - 1) ans = -1;
}

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= m; i ++ )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        edges[i] = {a, b, c};
    }
    
    for (int i = 1; i <= n; i ++ ) p[i] = i;
    
    kruscal();
    
    if (ans != -1) cout << ans << endl;
    else cout << "impossible";
    
    return 0;
    
}


posted @ 2026-04-04 11:40  blind5883  阅读(12)  评论(0)    收藏  举报