【bzoj3754】Tree之最小方差树 最小生成树
题目描述
输入
输出
样例输入
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之最小方差树 最小生成树的更多相关文章
- bzoj3754 Tree之最小方差树 最小生成树+推性质
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3754 题解 感觉这个思路挺神仙的. 后悔没有好好观察题目的数据范围,一直把 \(n\) 和 \ ...
- [BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树
[BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树 题目大意: 给定一个\(n(n\le50)\)个点,\(m(m\le1000 ...
- [BZOJ3754]Tree之最小方差树
3754: Tree之最小方差树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 402 Solved: 152[Submit][Status][Di ...
- 【枚举】【最小生成树】【kruscal】bzoj3754 Tree之最小方差树
发现,若使方差最小,则使Σ(wi-平均数)2最小即可. 因为权值的范围很小,所以我们可以枚举这个平均数,每次把边权赋成(wi-平均数)2,做kruscal. 但是,我们怎么知道枚举出来的平均数是不是恰 ...
- bzoj 3754: Tree之最小方差树 模拟退火+随机三分
题目大意: 求最小方差生成树.N<=100,M<=2000,Ci<=100 题解: 首先我们知道这么一个东西: 一些数和另一个数的差的平方之和的最小值在这个数是这些数的平均值时取得 ...
- 【BZOJ 3754】: Tree之最小方差树
题目链接: TP 题解: 都是骗子233,我还以为是什么神奇的算法. 由于边权的范围很小,最小生成树和最大生成树之间的总和差不会太大,所以可以枚举边权和,再直接根据方差建最小生成树,每次更新答案即可. ...
- BZOJ 3754 Tree之最小方差树 MST
Description Wayne 在玩儿一个很有趣的游戏.在游戏中,Wayne 建造了N 个城市,现在他想在这些城市间修一些公路,当然并不是任意两个城市间都能修,为了道路系统的美观,一共只有M 对城 ...
- 【BZOJ 3754】Tree之最小方差树
http://www.lydsy.com/JudgeOnline/problem.php?id=3754 核心思想:暴力枚举所有可能的平均数,对每个平均数排序后Kruskal. 正确的答案一定是最小的 ...
- BZOJ 3754 Tree之最小方差树
枚举平均数. mdzz编译器. #include<iostream> #include<cstdio> #include<cstring> #include< ...
随机推荐
- 5 Ways to Prevent the 300ms Click Delay on Mobile Devices
http://www.sitepoint.com/5-ways-prevent-300ms-click-delay-mobile-devices/
- Java设计模式(12)——结构型模式之门面模式(Facade)
一.概述 概念 简要示意图(没有一个统一的UML图) 角色 门面角色:门面模式核心,它被客户端调用,并且熟悉子系统 子系统角色:子系统,子系统并不知道门面的存在,门面对它来说只不过是另外一个客户端 ...
- WPF程序,运行时,结束时,要运行的操作(自动保存,检查单程序)
/// <summary> /// App.xaml 的交互逻辑 /// </summary> public partial class App : Application { ...
- 长沙Uber司机奖励政策(8月24日到8月30日)
本周奖励(8月24日到8月30日) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://w ...
- Unicode编码相关概念
1.Unicode是一种字符映射方案,这种映射并不是编码(即还没有到二进制机器码层面),而是像一个电话本一样,把全世界所有语言使用的字符,都映射成一个"u+"开头的数字(在JAVA ...
- quartz 核心概念
一.quartz 核心概念 1.scheduler是一个计划调度器容器,容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就 ...
- MongoDB-Ubuntu环境下安装
1.在官网下载安装包,下载后为 mongodb-linux-x86_64-ubuntu1604-3.4.6.tgz 解压:tar -zxvf mongodb-linux-x86_64-ubuntu16 ...
- Ceph性能优化
几个 Ceph 性能优化的新方法和思路(2015 SH Ceph Day 参后感) 一周前,由 Intel 与 Redhat 在10月18日联合举办了 Shanghai Ceph Day.在这次会议上 ...
- 可靠UDP,KCP协议快在哪?
WeTest 导读 云真机已经支持手机端的画面投影.云真机实时操作,对延迟的要求比远程视频对话的要求更高(100ms以内).在无线网络下,如何更实时.更可靠的传输视频流就成了一个挑战.通过websoc ...
- 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...