您的位置:首页 > 其它

BZOJ 3754 Tree之最小方差树

2016-08-20 10:21 344 查看
枚举平均数。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: