码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 3754 Tree之最小方差树

时间:2016-08-20 11:29:20      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

枚举平均数。

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;
}

 

BZOJ 3754 Tree之最小方差树

标签:

原文地址:http://www.cnblogs.com/ziliuziliu/p/5789774.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!