51Nod 1640 天气晴朗的魔法(最小生成树)

Posted shuitiangong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1640 天气晴朗的魔法(最小生成树)相关的知识,希望对你有一定的参考价值。

题目链接

解题思路

??看这题第一眼就想到了二分,虽然也过了不过还有一个更好的解法。本题的核心就是如何找到那条可以最小的最大的边(S),二分确实是一个办法,但是还有一种办法是求最小生成树,其最大边就是(S)
??因为最小生成树是将几条不重复的最小的边加入集合形成的树,那么如果要构造一棵树都所有边比最小生成树的最大边还小的话,是不可能的,不然,那棵最小生成树就不是最小生成树了,也可以说,根本构造不出来一棵这样的树。
??求出(S)之后就好办了,只需要构造一棵最大的生成树,其最大的边不超过(S)即可。

代码

const int maxn = 2e5+10;
int n, m, p[maxn]; ll ans, maxx=-1;
struct E {
    int u, v; ll w;
} e[maxn];
int find(int x) {
    return p[x]==x ? p[x] : p[x] = find(p[x]);
}
void merge(int a, int b) {
    p[find(a)] = find(b);
}
void kruskal(ll x) {
    ll sum = 0; 
    for (int i = 1; i<=n; ++i) p[i] = i;
    for (int i = 0; i<m; ++i)
        if (e[i].w<=x && find(e[i].u)!=find(e[i].v)) {
            merge(e[i].u, e[i].v);
            sum += e[i].w;
            maxx = max(maxx, e[i].w);
        }
    ans = sum;
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i<m; ++i) scanf("%d%d%lld", &e[i].u, &e[i].v, &e[i].w);
    sort(e, e+m, [](E a, E b){return a.w<b.w;});kruskal(LLONG_MAX);
    sort(e, e+m, [](E a, E b){return a.w>b.w;});kruskal(maxx);
    printf("%lld
", ans);
    return 0;
}


以上是关于51Nod 1640 天气晴朗的魔法(最小生成树)的主要内容,如果未能解决你的问题,请参考以下文章

51Nod 1640 天气晴朗的魔法(最小生成树)

51nod 1640 天气晴朗的魔法

51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了

1640 天气晴朗的魔法

51nod 1640 MST+二分

魔法跳舞链 (最小生成树)