码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 437D The Child and Zoo

时间:2020-02-03 18:56:22      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:double   while   +=   The   print   etc   main   opera   好的   

这个题还是很好的

有几个套路

先是我们看到题目中让我们处理点权,但是我们发现并不好处理

所以就先化点为边 (套路1)

把每一条边的边权视作边所连接的两个点的\(min\)

然后我们看到这个题有路径的问题,就先还是要较大的

可以比较显然地想到最大生成树 (套路2)

\(Kruskal\)中改一下排序方式就行了

然后我们看到不是生成树上的边都我们在考虑走的时候都不会考虑

考虑每一个树边的贡献

连接两个联通块的时候

这一条边会产生\(val[edge]* size[x]* size[y]\)的贡献 (套路3)

然后就是并查集完事

CODE:

#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm {
inline int read() {
    int res = 0, f = 1;
    char k;
    while (!isdigit(k = getchar())) {
        if (k == '-')
            f = -1;
    }
    while (isdigit(k)) {
        res = res * 10 + k - '0';
        k = getchar();
    }
    return res * f;
}
inline int max(int x, int y) { return x > y ? x : y; }
inline int min(int x, int y) { return x < y ? x : y; }
inline void swap(int &x, int &y) {
    int z = x;
    x = y;
    y = z;
    return;
}
const int N = 1e5 + 10;
const int M = 1e6 + 10;
struct node {
    int from, to, dis;
    bool operator<(const node &x) { return dis > x.dis; }
} e[M];
int n, m, val[N], sz[N], cnt, tot, fa[N];
inline void add(int u, int v, int w) {
    e[++cnt].dis = w;
    e[cnt].from = u;
    e[cnt].to = v;
    return;
}
inline int find(int x) { return fa[x] == x ? fa[x] : fa[x] = find(fa[x]); }
int u, v, w, ans;
signed main() {
    n = read();
    m = read();
    for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
    for (int i = 1; i <= n; ++i) val[i] = read();
    for (int i = 1; i <= m; ++i) u = read(), v = read(), add(u, v, min(val[u], val[v]));
    sort(e + 1, e + m + 1);
    for (int i = 1; i <= m; ++i) {
        int x = find(e[i].from), y = find(e[i].to);
        if (x == y)
            continue;
        fa[x] = y;
        tot++;
        ans += sz[x] * sz[y] * e[i].dis;
        sz[y] += sz[x];
        if (tot == n - 1)
            break;
    }
    ans *= 2;
    double x = n * (n - 1);
    printf("%.8lf", (double)ans / x);
    return 0;
}
}  // namespace yspm
signed main() {
    yspm::main();
    return 0;
}

Codeforces 437D The Child and Zoo

标签:double   while   +=   The   print   etc   main   opera   好的   

原文地址:https://www.cnblogs.com/yspm/p/12256494.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!