【学习笔记】最小直径生成树(MDST)
简介
无向图中某一点(可以在顶点上或边上),这个点到所有点的最短距离的最大值最小,那么这个点就是 图的绝对中心。
无向图所有生成树中,直径最小的一个,被称为 最小直径生成树。
图的绝对中心的求法
下文设 \(d(i, j)\) 为顶点 \(i,j\) 间的最短路径长。
首先我们考虑枚举每一条边 \((u, v)\),长为 \(L\),并假设绝对中心 \(p\) 在这条边上并且距离 \(u\) 长为 \(x(\le L)\)。
对于图中一点 \(i\),\(p\) 到 \(i\) 的距离可以写作 \(d(p, i) = \min(d(u, i) + x,\ d(v, i) + (L - x))\)。
那么显然可以看出 \(d(p, i)\) 的函数图像是一个 两条斜率相同的线段构成的折线段。
于是 \(p\) 到最远点距离的函数可以写作 \(f = \max\limits_{1\le i\le n}\{d(p, i)\}\),图像是一堆折线组成的 更加曲折的 折线,如图(来源):
图中的 \(\alpha\) 即为文中的 \(x\),\(\omega_{u, v}\) 即为 \(L\),\(w_{1\cdots n}\) 为图中异于 \(u, v\) 的点。
那么答案即为图像中的最低点,横坐标即为绝对中心的位置。
如何得到最低点?不难观察到最低点必然是两折线的交点。
对于图中的两点 \(i, j\),若 \(d(u, i) \ge d(u, j)\) 且 \(d(v, i) \ge d(v, j)\),那么显然这个 \(j\) 是丝毫不用考虑的——可以看出 \(d(p, j)\) 的函数图像是完全位于 \(d(p, i)\) 下方的,最低点显然不会在此。
这样筛出的 \(t\) 条折线会有 \(t - 1\) 个交点,那么只要根据这些交点更新答案即可。
\(O(t^2)\) 暴力枚举?大可不必。可以观察到,有一个性质,若我们将这些折线 按 \(d(u, i)\) 的大小 升序排序,那么对应 \(d(v, i)\) 的大小是 递减的。
于是排序后相邻两折线必定会有交点。
图的绝对中心的实现
设 \(adj(i, j)\) 为结点 \(i, j\) 间的直接距离(边长),\(d(i, j)\) 如上文所述,\(rk(i, j)\) 为距离点 \(i\) 第 \(j\) 远的点,\(f\) 即上文的函数。
这里 \(ans\) 表示最远距离。
- 首先使用多源最短路算法(Floyd,Johnson 等)求出 \(d\) 数组。
- 求出 \(rk\),对于每一个 \(i\),按关键字 \(d(i, j)\) 降序排序。
- 然后对于每一个点或边对答案进行更新:
- 可能在点上:对于每一个点 \(i\),用相对较远的点更新:\(ans \leftarrow \min(ans, d(i, rk(i, 1)))\)。
- 可能在边上:对于每一条边 \((i, j)\),从距离 \(i\) 最远的点开始验证——对于所有的 \(k(\le n)\):
- 若 \(d(j, rk(i, k-1)) \le d(j, rk(i, k))\),因为 \(rk\) 是根据 \(d(i, \cdots)\) 排序的,那么两者组合,发现这个对答案无贡献,不能计算,跳过。
- 否则就是 \(f\) 上的一个可能为答案的点(交点)。更新答案:\(ans\leftarrow \min(ans, \dfrac{d(i, rk(i, k)) + d(i, rk(i, k - 1)) + adj(i, j)}{2})\)。
最后 \(ans\) 即为所求。如果需要具体位置需要特别地在更新 \(ans\) 时记录。
复杂度 \(O(n^3 + nm)\) 或 \(O(nm\log n + nm)\),区别在于多源最短路的求法。对于无权图还可以直接 Bfs 得到更优秀的效率。
最小直径生成树(MDST)的求法
根据定义,易知图的绝对中心必定为 MDST 直径的中点。
那么只要得到绝对重心,MDST 并不难求——从绝对中心开始,生成一个最短路径树即为 MDST。
显然 MDST 的直径大小为 \(ans\times 2\)。
习题
- BZOJ 2180 - 最小直径生成树 / SPOJ MDST - Minimum Diameter Spanning Tree 【参考代码】
- SPOJ PT07C - The GbAaY Kingdom 【参考代码】
- Codeforces 266D - BerDonalds
后记
- 原文地址:https://www.cnblogs.com/-Wallace-/p/13483433.html
- 本文作者:@-Wallace-
- 转载请附上出处。
【学习笔记】最小直径生成树(MDST)的更多相关文章
- Hackerrank--Savita And Friends(最小直径生成树MDST)
题目链接 After completing her final semester, Savita is back home. She is excited to meet all her friend ...
- bzoj2180: 最小直径生成树
Description 输入一个无向图G=(V,E),W(a,b)表示边(a,b)之间的长度,求一棵生成树T,使得T的直径最小.树的直径即树的最长链,即树上距离最远的两点之间路径长度. Input 输 ...
- [学习笔记]最小割之最小点权覆盖&&最大点权独立集
最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...
- [学习笔记]最小割树(Gomory-Hu Tree)
最小割树(\(\mathcal{Gomory-Hu Tree}\))简明指南 对于单源最短路径,我们有\(SPFA\)和\(Dijkstra\),对于多源最短路径,我们有\(Floyd\):对于两点间 ...
- Spring学习笔记—最小化Spring XML配置
自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系. 自动 ...
- OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓
本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...
- Linux 学习笔记 1 使用最小的系统,从分区安装系统开始
我们常用的linux系统在安装过程中大多都省略了对系统进行分区的操作,以至于后期,不了解什么是分区以及分区当中最基本的一些概念, 我们不说最细的知识,只求了解这个过程,那直接步入正题,开始第一节的学习 ...
- 算法笔记_164:算法提高 最小方差生成树(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 给定带权无向图,求出一颗方差最小的生成树. 输入格式 输入多组测试数据.第一行为N,M,依次是点数和边数.接下来M行,每行三个整数U,V, ...
- 仙人掌&圆方树学习笔记
仙人掌&圆方树学习笔记 1.仙人掌 圆方树用来干啥? --处理仙人掌的问题. 仙人掌是啥? (图片来自于\(BZOJ1023\)) --也就是任意一条边只会出现在一个环里面. 当然,如果你的图 ...
随机推荐
- binary hacks读数笔记(od命令)
Linux od命令用于输出文件内容. od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来 -t<输出格式>或--format=<输出格式> 设置输出格式. 实例 ...
- Makefile 指定源文件目录 make
top=$(CURDIR) SRC_DIR=$(top)/src BUILD_DIR=$(SRC_DIR) src=$(wildcard $(SRC_DIR)/*.c) obj=$(patsubst ...
- python之迭代锁与信号量
如果现在需要在多处加锁大于等于2的时候 因为计算机比较笨,当他锁上一把锁的时候又所理一把锁,等他来开锁的时候他不知道用哪把钥匙来开锁, 所以这个时候我们需要把把平常的锁变为迭代锁 eg: import ...
- 一文看懂Java序列化之serialVersionUID
serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...
- linux帮助手册(help/man/info)
linux本身有数据库(数据库名whatis)--man实际是从whatis数据库里查找信息. makewhatis 刚装系统,若man不能用,用makewhatis命令.整理whatis数据库. 当 ...
- 蓝鲸平台开启consul.conf UI界面
#第一步: vi /data/bkce/etc/supervisor-consul.conf 修改参数: command=/usr/bin/consul agent -config-file=/dat ...
- MathType中余弦函数的输入
余弦函数是三角函数中十分重要的一个知识点,余弦函数的俩种形式分别为a2=b2+c2-2bccosA和cosA=(b2+c2-a2)/2bc,接下来我们分别介绍一下这俩种形式的输入. 具体步骤如下: 步 ...
- mysql 分组查询
mysql 分组查询 获取id最大的一条 (1)分组查询获取最大id SELECT MAX(id) as maxId FROM `d_table` GROUP BY `parent_id` ; (2) ...
- Mybatis【2.1】-- 从读取流到创建SqlSession发生了什么?
目录 1.Resources.getResourceAsStream("mybatis.xml")到底做了什么? 2. new SqlSessionFactoryBuilder() ...
- Spring Boot 2.x 多数据源配置之 MyBatis 篇
场景假设:现有电商业务,商品和库存分别放在不同的库 配置数据库连接 app: datasource: first: driver-class-name: com.mysql.cj.jdbc.Drive ...