• 【BZOJ 3754】: Tree之最小方差树


    题目链接:

      TP

    题解:

      都是骗子233,我还以为是什么神奇的算法。

      由于边权的范围很小,最小生成树和最大生成树之间的总和差不会太大,所以可以枚举边权和,再直接根据方差建最小生成树,每次更新答案即可。

    代码:

      

     1 #define Troy 
     2  
     3 #include <bits/stdc++.h>
     4  
     5 using namespace std;
     6  
     7 inline int read(){
     8     int s=0,k=1;char ch=getchar();
     9     while(ch<'0'|ch>'9')  ch=='-'?k=-1:0,ch=getchar();
    10     while(ch>47&ch<='9')  s=s*10+(ch^48),ch=getchar();
    11     return s*k;
    12 }
    13  
    14 int n,m,fa[101],sum;
    15 double ans;
    16  
    17 inline int finds(int x){
    18     return x==fa[x]?x:fa[x]=finds(fa[x]);
    19 }
    20  
    21 struct node{
    22     int u,v,c;
    23     double ave;
    24 }edge[2010];
    25  
    26 inline bool cmp1(const node &x,const node &y){
    27     return x.c<y.c;
    28 }
    29  
    30 inline bool cmp2(const node &x,const node &y){
    31     return x.ave<y.ave;
    32 }
    33  
    34 inline void MST(){
    35     for(int i=1;i<=n;++i)   fa[i]=i;
    36     sum=0;double now=0.0;
    37     for(int i=1,j=0;j^n-1;++i){
    38         int x=finds(edge[i].u),y=finds(edge[i].v);
    39         if(x!=y){
    40             // printf("edge[%d].ave=%f
    ",i,edge[i].ave);
    41             ++j;fa[y]=x;
    42             now+=edge[i].ave;sum+=edge[i].c;
    43         }
    44     }
    45     ans=min(ans,now);
    46 }
    47  
    48 inline double sqr(double x){
    49     return x*x;
    50 }
    51  
    52 inline void make(int tot){
    53     for(int i=1;i<=m;++i)
    54         edge[i].ave=sqr(edge[i].c-tot*1.0/(n-1));
    55     sort(edge+1,edge+1+m,cmp2);
    56 }
    57  
    58 int main(){
    59     n=read(),m=read();
    60     for(int i=1;i<=m;++i)   {
    61         int u=read(),v=read(),c=read();
    62         edge[i]=(node){u,v,c,0};
    63     }
    64     sort(edge+1,edge+m+1,cmp1);
    65     MST();int l=sum;
    66     for(int i=1;(i<<1)<=m;++i)swap(edge[i],edge[m-i+1]);
    67     MST();int r=sum;
    68     ans=1e16;
    69     // printf("l=%d r=%d
    ",l,r);
    70     for(int i=l;i<=r;++i){
    71         make(i);
    72         MST();
    73         // puts("");
    74     }
    75     printf("%.4f",sqrt(ans/(n-1)));
    76 }
  • 相关阅读:
    How To Change Database Name
    Oracle备份与恢复案例
    Linux 下安装 Oracle9i
    在 Linux x86 上安装 Oracle 数据库 10g_1
    在 Linux x86 上安装 Oracle 数据库 10g_2
    Oracle9i数据库DataGuard实施及维护手册2
    在 Linux x86 上安装 Oracle 数据库 10g_3
    流程企业(钢铁企业)的制造执行系统
    理解和使用Oracle分析工具LogMiner
    Oracle9i数据库Data Guard实施及维护手册 1
  • 原文地址:https://www.cnblogs.com/Troywar/p/7792404.html
Copyright © 2020-2023  润新知