zoukankan      html  css  js  c++  java
  • 【JZOJ3410】Tree【最小生成树】

    题目大意:

    求一张图的生成树,使得所有树边长度的标准差尽量小。
    标准差的定义:设有nn个数的aia_i,他们的平均数是aoverline{a},那么标准差就是i=1n(aia)2nsqrt{frac{sum^{n}_{i=1}(a_i-overline{a})^2}{n}}


    思路:

    由于标准差的大小和方差一致,方差的大小于绝对值之和一致。所以我们求转换成需要满足a1a+a2a+ana|a_1-overline{a}|+|a_2-overline{a}|+|a_n-overline{a}|尽量小。
    所以我们可以枚举每一个绝对值内部的正负,这样就可以脱掉绝对值了。
    我们可以假设一个midmid无限趋近于aoverline{a},那么我们就需要找到与midmid之差尽量小的边,并且这些边可以组成一棵生成树。
    显然我们只需要按照与midmid的差值排序,然后跑一遍最小生成树就行了。
    所以我们就枚举midmid,然后跑最小生成树,用这些边求出标准差即可。
    那么枚举midmid的误差应该在多少以内呢?
    我们假设有两条边的长度分别为5,75,7,那么我们枚举到6时,如果选择5会比选择7更优,但是我们是根据与midmid的差值排序的,此时两者一样,可能我们就优先选择7了。
    所以midmid的误差应该是小于1的。
    同理,如果取0.5的话,两条边长度为5和6,同样可能选择更劣的一条边。
    但是如果选择0.25的话,会选择劣势的边就只有两条边的长度只差为0.5,但是题目要求长度为整数,所以我们得到了如果2x<1,那么x就是一种可行的选择
    但是同时需要注意,我们枚举的误差xx一定要满足1xZ+frac{1}{x}in^+。这样就可以满足取多个midmid后一定可以从xx变成x+1x+1
    所以只要满足两个要求的误差即可:

    • x&lt;0.5x&lt;0.5
    • 1xZ+frac{1}{x}in^+

    这里我取的是误差=0.1=0.1。显然是满足以上要求的。


    代码:

    Download 
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N=5010;
    int n,m,tot,father[N];
    double ave,ans,sum,mid,dis[N];
    
    struct edge
    {
    	int from,to,dis;
    }e[N];
    
    bool cmp(edge x,edge y)
    {
    	return fabs((double)x.dis-mid)<fabs((double)y.dis-mid);
    }
    
    int find(int x)
    {
    	return x==father[x]?x:father[x]=find(father[x]);
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=m;i++)
    		scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].dis);
    	ans=1000000000000.0;
    	for (mid=0;mid<=100;mid+=0.1)
    	{
    		sort(e+1,e+1+m,cmp);
    		for (int i=1;i<=n;i++)
    			father[i]=i;
    		tot=0; ave=sum=0;
    		for (int i=1;i<=m;i++)
    		{
    			int x=e[i].from,y=e[i].to;
    			if (find(x)!=find(y))
    			{
    				dis[++tot]=(double)e[i].dis;
    				ave+=dis[tot];
    				father[find(x)]=find(y);
    			}
    		}
    		ave/=(double)(n-1);
    		for (int i=1;i<n;i++)
    			sum+=(dis[i]-ave)*(dis[i]-ave);
    		ans=min(ans,sqrt(sum/(double)(n-1)));
    	}
    	printf("%0.4lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    python,生产环境安装
    neo4j 图数据库
    RNN系列
    机器学习关于AUC的理解整理
    fensorflow 安装报错 DEPENDENCY ERROR
    dubbo Failed to check the status of the service com.user.service.UserService. No provider available for the service
    使用hbase遇到的问题
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk
    gradle 安装
    jenkins 安装遇到的坑
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998038.html
Copyright © 2011-2022 走看看