zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    录屏软件 OBS Studio
    ubuntu安装以及美化
    win10系统软件安装列表
    GNSS数据的弱点
    理解TomoDD生成的地壳模型的格式
    acrobat DC install
    matlab平行运算 parrelpool
    写申请地震台网数据的申请表
    强震动数据的网站
    visual studio各个版本的key
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12967824.html
Copyright © 2011-2022 走看看