原題網址:http://www.lydsy.com/JudgeOnline/problem.php?id=3754
思路有點像分數規劃,分數規劃是二分答案,根據答案每一個選項之間就有了優劣之分。一般的MST要每次取邊權最小的,但是這一題要方差最小,那麼邊與邊之間就沒有直接的優劣之分,那麼我們枚舉平均數,對於每條邊,我們算出
#include<bits/stdc++.h>
const int N = 105;
const int M = 2050;
int n,m,fa[N];
struct rec{int u,v,c;double x;} a[M];
bool cmp(const rec &a, const rec &b){
return a.x < b.x;
}
double sqr(double x){
return x * x;
}
int find(int x){
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1; i<=m; i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].c);
int ans = 1e9;
for (double ave=0; ave<=100; ave+=0.25){
for (int i=1; i<=m; i++) a[i].x = sqr(a[i].c - ave);
std::sort(a+1,a+m+1,cmp);
for (int i=1; i<=n; i++) fa[i] = i;
int sum = 0, sum2 = 0;
for (int i=1; i<=m; i++){
int f1 = find(a[i].u);
int f2 = find(a[i].v);
if (f1 == f2) continue;
fa[f1] = f2;
sum += a[i].c;
sum2 += a[i].c * a[i].c;
}
ans = std::min(ans,(n-1)*sum2-sum*sum);
}
printf("%.4f\n",sqrt(ans)/(n-1));
return 0;
}