• Codeforces 437D The Child and Zoo(贪心+并查集)


    题目链接:Codeforces 437D The Child and Zoo

    题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值。然后有m条路,每条路的权值为该条路连接的两个区中权值较小的一个。假设两个区没有直接连接,那么f值即为从一个区走到还有一个区中所经过的路中权值最小的值做为权值。问,平均两个区之间移动的权值为多少。

    解题思路:并查集+贪心。将全部的边依照权值排序,从最大的開始连接,每次连接时计算的次数为连接两块的节点数的积(乘法原理)。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int N = 1e5+5;
    
    struct edge {
        int u, v, w;
    }e[N];
    
    int n, m, f[N], c[N], w[N];
    
    bool cmp (const edge& a, const edge& b) {
        return a.w > b.w;
    }
    
    int getfar (int x) {
        return x == f[x] ? x : f[x] = getfar(f[x]);
    }
    
    void init () {
        scanf("%d%d", &n, &m);
    
        for (int i = 1; i <= n; i++) {
            f[i] = i;
            c[i] = 1;
            scanf("%d", &w[i]);
        }
    
        for (int i = 0; i < m; i++) {
            scanf("%d%d", &e[i].u, &e[i].v);
            e[i].w = min(w[e[i].u], w[e[i].v]);
        }
    
        sort(e, e + m, cmp);
    }
    
    int main () {
        init();
        double ans = 0;
    
        for (int i = 0; i < m; i++) {
            int p = getfar(e[i].u);
            int q = getfar(e[i].v);
    
            if (p != q) {
                ans += (double)e[i].w * c[p] * c[q];
                c[p] += c[q];
                f[q] = p;
            }
        }
        printf("%.6lf
    ", ans * 2 / (n * 1.0 * (n-1)));
        return 0;
    }
  • 相关阅读:
    谷粒商城Day1
    解决GitHub访问慢的问题
    Java基础知识面试题
    Spring框架学习
    MATLAB基础学习(3)——数值数组及运算
    MATLAB基础学习(2)
    MATLAB基础学习篇(1)
    页面加载之前显示正在加载
    CSS设置多余的文本显示省略号
    Node.js(六)- HTTP知识先填坑
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4287757.html
Copyright © 2020-2023  润新知