题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=3754

题解

感觉这个思路挺神仙的。

后悔没有好好观察题目的数据范围,一直把 \(n\) 和 \(m\) 当成 1e5 来思考,\(c\) 竟然也只有 \(100\)。


有了数据范围以后可以发现,边权和位于 \(nc\) 级别,大概就是 \(10000\) 左右。

所以我们可以考虑枚举边权和,从而得到边权的平均数。

然后我们给每一条边的边权赋值为 \((\)原始边权 \(-\) 平均数\()^2\)。这样求出最小生成树。

但是有一个问题就是我们求出来的最小生成树的边权和不一定就是我们枚举的边权和。

不过很容易发现如果边权和不是我们枚举的边权和,那么我们在实际的边权和的地方计算出来的结果一定比这个优。所以没有影响。

上面的结论证明的话,大概就是考虑实际边权和为 \(s\),实际平方和为 \(t\)。我们枚举的平均数为 \(v\)。

\[\begin{align*}
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)\)。

我跑的好慢啊。

  1. #include<bits/stdc++.h>
  2. #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
  3. #define dbg(...) fprintf(stderr, __VA_ARGS__)
  4. #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
  5. #define fi first
  6. #define se second
  7. #define pb push_back
  8. template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
  9. template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
  10. typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
  11. template<typename I> inline void read(I &x) {
  12. int f = 0, c;
  13. while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
  14. x = c & 15;
  15. while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
  16. f ? x = -x : 0;
  17. }
  18. const int N = 100 + 7;
  19. const int M = 1000 + 7;
  20. int n, m;
  21. int fa[N];
  22. struct Edges { int x, y, z; double w; } e[M];
  23. inline bool operator < (const Edges &a, const Edges &b) { return a.w < b.w; }
  24. inline bool operator > (const Edges &a, const Edges &b) { return a.w > b.w; }
  25. inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
  26. inline double kruskal(bool flag = 0) {
  27. if (!flag) std::sort(e + 1, e + m + 1);
  28. else std::sort(e + 1, e + m + 1, std::greater<Edges>());
  29. for (int i = 1; i <= n; ++i) fa[i] = i;
  30. double ans = 0;
  31. for (int i = 1; i <= m; ++i) {
  32. int x = find(e[i].x), y = find(e[i].y);
  33. if (x == y) continue;
  34. fa[y] = x, ans += e[i].w;
  35. }
  36. return ans;
  37. }
  38. inline void work() {
  39. int l = kruskal(), r = kruskal(1);
  40. double ans = 1e10;
  41. for (int i = l; i <= r; ++i) {
  42. double v = (double)i / (n - 1);
  43. for (int j = 1; j <= m; ++j) e[j].w = (e[j].z - v) * (e[j].z - v);
  44. smin(ans, kruskal());
  45. }
  46. printf("%.4lf\n", sqrt(ans / (n - 1)));
  47. }
  48. inline void init() {
  49. read(n), read(m);
  50. 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;
  51. }
  52. int main() {
  53. #ifdef hzhkk
  54. freopen("hkk.in", "r", stdin);
  55. #endif
  56. init();
  57. work();
  58. fclose(stdin), fclose(stdout);
  59. return 0;
  60. }

bzoj3754 Tree之最小方差树 最小生成树+推性质的更多相关文章

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

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

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

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

  3. 【bzoj3754】Tree之最小方差树 最小生成树

    题目描述 给出一张无向图,求它的一棵生成树,使得选出的所有边的方差最小.输出这个最小方差. 输入 第一行两个正整数N,M 接下来M行,每行三个正整数Ui,Vi,Ci N<=100,M<=2 ...

  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. HTML学习之==>JS

    HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...

  2. 2.k8s.Pod生命周期,健康检查

    #Pod生命周期,健康检查 pod创建过程 Init容器 就绪探测 存活探测 生命周期钩子 #Pod创建过程 master节点:kubectl -> kube-api -> kubenle ...

  3. wpf datagrid tooltip

    <DataGridTemplateColumn Header="购方名称" Width="260" HeaderStyle="{StaticRe ...

  4. office问题解决办法汇总

    1.Office2007或2010提示:您正试图运行的函数包含有宏或需要宏语言支持的内容 解决办法:word选项--加载项--管理com加载项--转到--把所有加载项删除 2.excel2010打开三 ...

  5. numpy2

    1.通用函数,是一种在ndarray数据中进行逐元素操作的函数.某些函数接受一个或多个标量数值,并产生一个或多个标量结果,通用函数就是对这些函数的封装. 1.常用的一元通用函数有:abs\fabs s ...

  6. java.lang.NoSuchMethodError: org.apache.spark.internal.Logging.$init$(Lorg/apache/spark/internal/Logging;)V

    1.sparkML的版本不对应 请参考官网找到对于版本, 比如我的 spark2.3.3          spark MLlib 也是2.3.3

  7. 20191114 Spring Boot官方文档学习(4.7)

    4.7.开发Web应用程序 Spring Boot非常适合于Web应用程序开发.您可以使用嵌入式Tomcat,Jetty,Undertow或Netty创建独立的HTTP服务器.大多数Web应用程序都使 ...

  8. 20191127 Spring Boot官方文档学习(9.1-9.3)

    9."使用方法"指南 9.1.Spring Boot应用程序 9.1.1.创建自己的FailureAnalyzer FailureAnalyzer被包装在FailureAnalys ...

  9. [DS+Algo] 009 树的介绍

    目录 1. 树的概念 2. 树的术语 3. 树的种类 4. 常见应用场景 5. 二叉树 1. 树的概念 每个结点(节点)有 0 个或多个子结点 没有父结点的结点称为根结点 每一个非根结点有且只有一个父 ...

  10. spring - 第N篇 一些笔记

    1.properties文件的引入 <bean id="propertyConfigurer" class="org.springframework.beans.f ...