bzoj3754 Tree之最小方差树 最小生成树+推性质
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=3754
题解
感觉这个思路挺神仙的。
后悔没有好好观察题目的数据范围,一直把 \(n\) 和 \(m\) 当成 1e5 来思考,\(c\) 竟然也只有 \(100\)。
有了数据范围以后可以发现,边权和位于 \(nc\) 级别,大概就是 \(10000\) 左右。
所以我们可以考虑枚举边权和,从而得到边权的平均数。
然后我们给每一条边的边权赋值为 \((\)原始边权 \(-\) 平均数\()^2\)。这样求出最小生成树。
但是有一个问题就是我们求出来的最小生成树的边权和不一定就是我们枚举的边权和。
不过很容易发现如果边权和不是我们枚举的边权和,那么我们在实际的边权和的地方计算出来的结果一定比这个优。所以没有影响。
上面的结论证明的话,大概就是考虑实际边权和为 \(s\),实际平方和为 \(t\)。我们枚举的平均数为 \(v\)。
Sum &= \sum (a_i - v) ^ 2\\
&= \sum a_i^2 - 2a_iv + nv^2\\
&= t - 2sv + nv^2
\end{align*}
\]
显然当 \(v = \frac sn\) 的时候最优,也就是 \(v\) 就是平均数的时候最优。
时间复杂度 \(O(ncm\log m)\)。
我跑的好慢啊。
#include<bits/stdc++.h>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const int N = 100 + 7;
const int M = 1000 + 7;
int n, m;
int fa[N];
struct Edges { int x, y, z; double w; } e[M];
inline bool operator < (const Edges &a, const Edges &b) { return a.w < b.w; }
inline bool operator > (const Edges &a, const Edges &b) { return a.w > b.w; }
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline double kruskal(bool flag = 0) {
if (!flag) std::sort(e + 1, e + m + 1);
else std::sort(e + 1, e + m + 1, std::greater<Edges>());
for (int i = 1; i <= n; ++i) fa[i] = i;
double ans = 0;
for (int i = 1; i <= m; ++i) {
int x = find(e[i].x), y = find(e[i].y);
if (x == y) continue;
fa[y] = x, ans += e[i].w;
}
return ans;
}
inline void work() {
int l = kruskal(), r = kruskal(1);
double ans = 1e10;
for (int i = l; i <= r; ++i) {
double v = (double)i / (n - 1);
for (int j = 1; j <= m; ++j) e[j].w = (e[j].z - v) * (e[j].z - v);
smin(ans, kruskal());
}
printf("%.4lf\n", sqrt(ans / (n - 1)));
}
inline void init() {
read(n), read(m);
for (int i = 1; i <= m; ++i) read(e[i].x), read(e[i].y), read(e[i].z), e[i].w = e[i].z;
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}
bzoj3754 Tree之最小方差树 最小生成树+推性质的更多相关文章
- [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 ...
- 【bzoj3754】Tree之最小方差树 最小生成树
题目描述 给出一张无向图,求它的一棵生成树,使得选出的所有边的方差最小.输出这个最小方差. 输入 第一行两个正整数N,M 接下来M行,每行三个正整数Ui,Vi,Ci N<=100,M<=2 ...
- 【枚举】【最小生成树】【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< ...
随机推荐
- mysql 优化之索引的使用
mysql 优化之索引的使用 1:MySQL 索引简介: MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL ...
- windows下eclipse打不开
报错找不到jre等东西 因为eclipse到不到javaw.exe 将其写入eclipse.ini即可 在eclipse.ini的前面加上 -vm D:\dev_tool\java\jdk1.7.0_ ...
- 浏览器端-W3School:JS & DOM 参考手册
ylbtech-浏览器端-W3School:JS & DOM 参考手册 1.返回顶部 1. JavaScript 参考手册 本部分提供完整的 JavaScript 参考手册: JavaScri ...
- Go开发[八]goroutine和channel
进程和线程 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位. 一个进程可以创 ...
- Python Module_subprocess_子进程(程序调用)
目录 目录 前言 软件环境 认识subprocess Popen Constructor构造函数 Class Popen的参数 args 调用程序 调用Shell指令 stdinstdoutstder ...
- for...in 、Object.keys 、 Object.getOwnPropertyNames
个人总结: 1.for...in 遍历的是对象的可枚举,非Symbol属性(包括自身和原型上的) 2.Object.keys 返回一个数组,是对象自身的可枚举属性 (非Symbol) 3.Object ...
- vs2010发布网站时有些文件没有发布出去的解决办法。
项目中包含了一些ttf字体文件做为图标使用,可是发布时发现生成的目录中没有这个文件,这种情况这么设置一下就可以解决: 1,在文件上点击右键,选择“属性”. 2,在弹出的属性窗口中,更改“生成操作”为“ ...
- 将python 2.6 升级到 2.7,及pip安装
由于CentOS6.5 自带python版本为2.6.6,实际中使用的大多为2.7.x版本.于是手动升级. 查看python的版本 #python -VPython 2.6.6 1.下载Python- ...
- docker私有仓库-harbor
简单说一下Harbor的部署,踩了几个坑,参考同事大神的配置文件,一脸懵逼的部署出来了,其中部分内容参考了网上一些大神的文档,本篇文章仅供参考学习,如有雷同,万分荣幸. 这篇文档仅限于centos7参 ...
- 初识HTML标签
web概念概述 JavaWeb: 使用Java语言开发基于互联网的项目 软件架构: C/S: Client/Server 客户端/服务器端 在用户本地有一个客户端程序,在远程有一个服务器端程序 如:Q ...