分析:
最小方差生成树
发现
c
i
c_i
ci很小 可以考虑枚举平均值
f
f
f 按
(
a
i
−
f
)
2
(a_i-f)^2
(ai−f)2排序建最小生成树 再每次求方差
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=2005;
int n,m,fa[N];
double ans=0x3f3f3f3f,tmp,edge[N];
struct node{
int x,y,k;
}a[N<<1];
bool cmp(node x,node y){return fabs(x.k*1.0-tmp)<fabs(y.k*1.0-tmp);}
int find(int x){return x==fa[x]?x: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].x,&a[i].y,&a[i].k);
for(double k=0;k<=100;k+=0.1)
{
double sum=0,avg=0,res=0;
int tot=0; tmp=k;
for(int i=1;i<=n;i++) fa[i]=i;
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;i++)
{
int fx=find(a[i].x),fy=find(a[i].y);
if(fx^fy)
{
fa[fx]=fy;
edge[++tot]=(double)a[i].k;
sum+=edge[tot];
}
if(tot==n-1) break;
}
avg=sum/(double)tot;
for(int i=1;i<=tot;i++)
res+=(edge[i]-avg)*(edge[i]-avg);
res/=(double)tot; res=sqrt(res);
ans=min(ans,res);
}
printf("%.4lf",ans);
return 0;
}