# 【BZOJ 3754】Tree之最小方差树

http://www.lydsy.com/JudgeOnline/problem.php?id=3754

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 103;
const int M = 2003;

int now, mn, ma, n, m, tot = 0, cnt, fa[N], a[N], suma;
double ab, S, ans = -1;
struct Edge {
int u, v, e;
double w;
Edge(int _u = 0, int _v = 0, int _e = 0, double _w = 0)
: u(_u), v(_v), e(_e), w(_w) {}
bool operator < (const Edge &A) const {
return w < A.w;
}
} G[M];

int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}

double sqr(double x) {return x * x;}

int u, v, e;

double Kru() {
for (int i = 1; i <= n; ++i) fa[i] = i;
cnt = 0; S = 0;
for (int i = 1; i <= tot; ++i) {
u = find(G[i].u); v = find(G[i].v);
if (u != v) {
++cnt;
fa[u] = v;
S += G[i].w;
if (cnt == n - 1)
break;
}
}
return S;
}

int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i) {
scanf("%d%d%d", &u, &v, &e);
G[++tot] = Edge(u, v, e, (double) e);
}

stable_sort(G + 1, G + tot + 1);
mn = (int) Kru();
reverse(G + 1, G + tot + 1);
ma = (int) Kru();

for (now = mn; now <= ma; ++now) {
ab = (double) now / (n - 1);
for (int i = 1; i <= tot; ++i)
G[i].w = sqr(ab - G[i].e);
stable_sort(G + 1, G + tot + 1);
S = Kru();
ans = ans == -1 ? S : min(ans, S);
}

printf("%.4lf\n", sqrt(ans / (n - 1)));
return 0;
}

NOI 2017 Bless All
posted @ 2016-11-15 20:31  abclzr  阅读(171)  评论(0编辑  收藏  举报