最大生成树

图片说明

题目分析:第一次遇见最大生成树的题目,但是它的代码几乎和最小生成树一模一样,唯一不同的就是在排序的时候把最大的边放在前面,那么我们选择的时候就是从最大的边开始,这样一来,遍历完之后,最大生成树就求出来了,刚开始看见这个题目的时候,没看懂最后一句话,说的是dis(u,v)表示路径中的最短的边的边权,但是选择的时候又选择最大的路径,反反复复不是很理解,一看题解,原来是一个最大生成树问题,也就是说在构成通路的基础上,每条边选择最大的边权。

方法一:直接建树

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int pre[maxn];
struct node
{
    int a, b, c;
    bool operator<(const node x) const
    {
        return c > x.c;
    }
} w[maxn];

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

void join(int x, int y)
{
    pre[find(x)] = find(y);
}
int main()
{
    int n, m;
    while (~scanf("%d%d", &n, &m))
    {
        ll ans = 0;
        for (int i = 1; i <= n; ++i)
            pre[i] = i;
        for (int i = 1; i <= m; ++i)
            scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
        sort(w + 1, w + m + 1);
        for (int i = 1; i <= m; ++i)
            if (find(w[i].a) != find(w[i].b))
            {
                join(w[i].a, w[i].b);
                ans += w[i].c;
            }
        printf("%lld\n", ans);
    }
    return 0;
}

方法二:先判断再加边

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int pre[maxn];
struct node
{
    int a, b, c;
    bool operator<(const node x) const
    {
        return c > x.c;
    }
} w[maxn];

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

int join(int x, int y)
{
    int a = find(x);
    int b = find(y);
    if (a != b)
    {
        pre[a] = b;
        return 1;
    }
    return 0;
}
int main()
{
    int n, m;
    while (~scanf("%d%d", &n, &m))
    {
        ll ans = 0;
        for (int i = 1; i <= n; ++i)
            pre[i] = i;
        for (int i = 1; i <= m; ++i)
            scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
        sort(w + 1, w + m + 1);
        for (int i = 1; i <= m; ++i)
            if (join(w[i].a, w[i].b))
            {
                join(w[i].a, w[i].b);
                ans += w[i].c;
            }
        printf("%lld\n", ans);
    }
}