题目描述

给出一张无向图,求它的一棵生成树,使得选出的所有边的方差最小。输出这个最小方差。

输入

第一行两个正整数N,M
接下来M行,每行三个正整数Ui,Vi,Ci
N<=100,M<=2000,Ci<=100

输出

输出最小的标准差,保留四位小数。

样例输入

3 3
1 2 1
2 3 2
3 1 3

样例输出

0.5000


题解

最小生成树

由于Ci很小,因此选出边的总和不会很大。可以考虑枚举这个总和(即平均值)。

然后把每条边的边权看作 $|c_i-\bar c|$ ,跑最小生成树,记录选出的边,然后根据实际选择计算实际方差(注意这里算平均值用的不是枚举的总和,而是实际计算的平均值)

简单证明一下这样为什么是对的:当枚举的总和是最终答案的总和时,选出的边一定是最终答案,而每次计算的答案不会出现错误情况,因此它们的最小值一定是答案。

细节处理中,可以先对所有边按照权值排序,在枚举总和(平均值)时,记录第一个大于等于这个平均值的边的位置 $p$ 。这样,这个位置 $p$ 左边的代价就是 $\bar c-c_i$ ,右边的代价就是 $c_i-\bar c$ ,使用二路归并的方法依次取最小值即可。这个方法可以避免每次都对所有边排序。

时间复杂度 $O(m\log m+cnm)$

#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
struct data
{
int x , y , z;
bool operator<(const data &a)const {return z < a.z;}
}a[2010];
bool v[2010];
int f[110];
int find(int x)
{
return x == f[x] ? f[x] : f[x] = find(f[x]);
}
int main()
{
int n , m , i , j , k , now , p = 1;
double s , t , ans = 1 << 30;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d" , &a[i].x , &a[i].y , &a[i].z);
sort(a + 1 , a + m + 1);
for(i = 0 ; i <= (n - 1) * 100 ; i ++ )
{
while(p <= m && a[p].z * (n - 1) < i) p ++ ;
for(j = 1 ; j <= n ; j ++ ) f[j] = j;
for(j = 1 ; j <= m ; j ++ ) v[j] = 0;
j = p - 1 , k = p , s = t = 0;
while(j || k <= m)
{
if(k > m || (j && i - a[j].z * (n - 1) < a[k].z * (n - 1) - i)) now = j -- ;
else now = k ++ ;
if(find(a[now].x) != find(a[now].y))
f[f[a[now].x]] = f[a[now].y] , s += a[now].z , v[now] = 1;
}
s /= (n - 1);
for(j = 1 ; j <= m ; j ++ )
if(v[j])
t += (a[j].z - s) * (a[j].z - s);
ans = min(ans , t);
}
printf("%.4lf\n" , sqrt(ans / (n - 1)));
return 0;
}

【bzoj3754】Tree之最小方差树 最小生成树的更多相关文章

  1. bzoj3754 Tree之最小方差树 最小生成树+推性质

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3754 题解 感觉这个思路挺神仙的. 后悔没有好好观察题目的数据范围,一直把 \(n\) 和 \ ...

  2. [BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树

    [BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树 题目大意: 给定一个\(n(n\le50)\)个点,\(m(m\le1000 ...

  3. [BZOJ3754]Tree之最小方差树

    3754: Tree之最小方差树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 402  Solved: 152[Submit][Status][Di ...

  4. 【枚举】【最小生成树】【kruscal】bzoj3754 Tree之最小方差树

    发现,若使方差最小,则使Σ(wi-平均数)2最小即可. 因为权值的范围很小,所以我们可以枚举这个平均数,每次把边权赋成(wi-平均数)2,做kruscal. 但是,我们怎么知道枚举出来的平均数是不是恰 ...

  5. bzoj 3754: Tree之最小方差树 模拟退火+随机三分

    题目大意: 求最小方差生成树.N<=100,M<=2000,Ci<=100 题解: 首先我们知道这么一个东西: 一些数和另一个数的差的平方之和的最小值在这个数是这些数的平均值时取得 ...

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

    题目链接: TP 题解: 都是骗子233,我还以为是什么神奇的算法. 由于边权的范围很小,最小生成树和最大生成树之间的总和差不会太大,所以可以枚举边权和,再直接根据方差建最小生成树,每次更新答案即可. ...

  7. BZOJ 3754 Tree之最小方差树 MST

    Description Wayne 在玩儿一个很有趣的游戏.在游戏中,Wayne 建造了N 个城市,现在他想在这些城市间修一些公路,当然并不是任意两个城市间都能修,为了道路系统的美观,一共只有M 对城 ...

  8. 【BZOJ 3754】Tree之最小方差树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3754 核心思想:暴力枚举所有可能的平均数,对每个平均数排序后Kruskal. 正确的答案一定是最小的 ...

  9. BZOJ 3754 Tree之最小方差树

    枚举平均数. mdzz编译器. #include<iostream> #include<cstdio> #include<cstring> #include< ...

随机推荐

  1. Python CSV模块简介

    Table of Contents 1. CSV 1.1. 简介 1.2. 字典方式地读写 1.3. 其它 2. 参考资料 CSV csv文件格式是一种通用的电子表格和数据库导入导出格式.最近我调用R ...

  2. 20145202mc《计算机病毒》实践2

    网站检测 http://www.virustotal.com太慢了实在,所以我换成了http://www.virscan.org/ lab01-01.exe 文件行为 lab01-01.dll 可以基 ...

  3. git 取消commit

    git如何撤销上一次commit操作 1.第一种情况:还没有push,只是在本地commit git reset --soft|--mixed|--hard <commit_id> git ...

  4. dubbo入门(一)

    1.简介 Dubbo由阿里巴巴开源,是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用)远程服务调用方案,以及SOA服务治理方案.如果没有分布式的需求,Dbubbo是不需要的,其本质 ...

  5. Selenium 入门到精通系列:二

    Selenium 入门到精通系列 PS:用户登录 例子 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2019-04-23 16:12 ...

  6. Linux命令应用大词典-第6章 文件处理

    6.1 sort:对文件中的数据进行排序 6.2 uniq:将重复行从输出文件中删除 6.3 cut:从文件每行中输出选定的字节.字符或字段 6.4 comm:逐行比较两个已经排序的文件 6.5 di ...

  7. 只写Python一遍代码,就可以同时生成安卓及IOS的APP,真优秀

    前言: 用Python写安卓APP肯定不是最好的选择,但是肯定是一个很偷懒的选择 我们使用kivy开发安卓APP,Kivy是一套专门用于跨平台快速应用开发的开源框架,使用Python和Cython编写 ...

  8. org.apache.spark.launcher.Main源码分析

    public static void main(String[] argsArray) throws Exception { //org.apache.spark.launcher.Main chec ...

  9. Scala学习笔记之Actor多线程与线程通信的简单例子

    题目:通过子线程读取每个文件,并统计单词数,将单词数返回给主线程相加得出总单词数 package review import scala.actors.{Actor, Future} import s ...

  10. 【第一章】MySQL数据概述

    安装部署 备份恢复主备复制读写分离HA架构分布式数据库压力测试性能优化自动化运维 ==数据的存储方式1. 人工管理阶段2. 文件系统阶段3. 数据库系统管理阶段 ==数据库技术构成1. 数据库系统 D ...