枚举平均数。
mdzz编译器。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxv 100500 #define maxe 200500 using namespace std; int n,m,l=0,r=0,father[maxv],rank[maxv]; double ans=999999999999999999999999999999.0; struct edge { int u,v,w; double val; }e[maxe]; bool cmp1(edge x,edge y) { return x.w<y.w; } bool operator < (const edge &a,const edge &b){return a.val<b.val;} int getfather(int x) { if (father[x]!=x) father[x]=getfather(father[x]); return father[x]; } void unionn(const int u,const int v) { if(rank[u]<rank[v]) father[u]=v; else { father[v]=u; if(rank[u]==rank[v]) ++rank[u]; } } double sqr(const double &x){return x*x;} void kruskal(const int &x) { int sum1=0,cnt=0; double sum2=0,ww=(double)x/(double)(n-1); for (int i=1;i<=n;i++) father[i]=i; memset(rank,0,sizeof(rank)); for (int i=1;i<=m;i++) e[i].val=sqr(e[i].w-ww); sort(e+1,e+m+1); for(int i=1;i<=m;i++) { int f1=getfather(e[i].u),f2=getfather(e[i].v); if(f1!=f2) { unionn(f1,f2); sum1+=e[i].w; sum2+=e[i].val; if((++cnt)==n-1) break; } } if (sum1==x) ans=min(ans,sum2); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); sort(e+1,e+m+1,cmp1); for (int i=1;i<=n-1;i++) l+=e[i].w; for (int i=m-n+2;i<=m;i++) r+=e[i].w; for (int i=l;i<=r;i++) kruskal(i); printf("%.4f\n",sqrt(ans/(double)(n-1))); return 0; }