ch10 题目参考思路
ch10 - 最小生成树
有线通讯网
- 知识点:Prim 算法
- 思路:
- 该题要求对 n 座城市铺设 n - 1 条光缆,并要求所有城市连通,那本质上是一棵树,又要求铺设光缆的费用最低,即要求选取的 n - 1 条光缆的长度最小,自然想到这题其实是求最小生成树,并求对应的边权和。
- 由题意知,任意两点之间的边权等于两点之间的距离
- 由于此题边数很大,任意两点之间都有一条边,因此考虑使用 Prim 算法解决
- 该题要求对 n 座城市铺设 n - 1 条光缆,并要求所有城市连通,那本质上是一棵树,又要求铺设光缆的费用最低,即要求选取的 n - 1 条光缆的长度最小,自然想到这题其实是求最小生成树,并求对应的边权和。
卫星通讯网
- 知识点:Prim 算法
- 思路:
- 题目的意思是,给定 n 个点,要求将其分成 k 个连通块,使得总的边权和最小。
- 先从简单的想起,假设 k = 1,要想使得总边权和最小,那自然是最小生成树的边权和。
- 再考虑 k = 2,这时可以多分出一个连通块,那么显然去掉最小生成树中的一条边就可以变成两个连通块,显然应该去掉之前最小生成树中权值最大的边。
- 思考:为什么不重新考虑构建两个连通块,而是在最小生成树的基础上操作?本质是一样的。因为假设存在两个新的连通块,对每个连通块内部算一次最小生成树,那么这两个树要么是之前整个最小生成树的子树,要么权值和与对应的子树相同,不会更优,因此实际上也等价于在整个最小生成树上删除了一条边。
- 同理,依次类推,如果要分成 k 个连通块,只需要删除边权最大的 k - 1 条边即可
- 可以在进行 Prim 算法的时候,通过一个大根堆来存储所有边权,最后从答案中去掉边权最大的 k - 1 条边即可
- 再考虑 k = 2,这时可以多分出一个连通块,那么显然去掉最小生成树中的一条边就可以变成两个连通块,显然应该去掉之前最小生成树中权值最大的边。
「USACO 07DEC」Building Roads
- 知识点:最小生成树
- 思路:
- 原问题可以成是一个有着 n 个节点的完全图,实质上为最小生成树求解的问题(连通所有节点,且总边权和最小),其中已有的边可以认为边权为 0(不会对答案产生贡献)。
- 原图可以视为一个完全图,边数较多,考虑使用 prim 算法解决(由于 n 只有 1000,用 kruskal 算法解决也可以)
「USACO 08OCT」Watering Hole
- 知识点:最小生成树
- 思路:
- 将 n 个农场看成图上的 n 个节点,任意两点间都有一条边,连接一条边有相应的花费(边权),并且在一个结点上建立一个水井也有花费,同样是花费,能否将建立水井的过程也同样看成是一条边呢(边权是建水井的花费)?每个点都有一条边,这些边应该连向哪里(它们都能产生一个水井,水井之间没有区别)?
- 根据题意,要求每个农场(节点)都要和水井相连,因此考虑新建一个 “超级水井”(新增节点),所有建立水井的边都连上这个 “超级水井”,与该 “超级水井” 直接、或间接相连的点都能连通到该水井上(满足题目连水井的要求)
- 题目又要求总花费最少,考虑在该图上求最小生成树的边权和,这样能保证所有节点都能连到超级水井上,且总代价最小。
- 综上所述,考虑设定节点 n + 1 为 “超级水井” 节点,每个普通节点 i 连向 n + 1 节点的边权为在节点 i 上建立水井的代价,对这样一个 n + 1 节点的图求最小生成树的边权和即可。
- 将 n 个农场看成图上的 n 个节点,任意两点间都有一条边,连接一条边有相应的花费(边权),并且在一个结点上建立一个水井也有花费,同样是花费,能否将建立水井的过程也同样看成是一条边呢(边权是建水井的花费)?每个点都有一条边,这些边应该连向哪里(它们都能产生一个水井,水井之间没有区别)?
「USACO 19OPEN」I Would Walk 500 Miles
-
知识点:最小生成树
-
思路:
- 题意:可以将每头奶牛看成一个节点,任意两头奶牛之间都有一条边(边权为两个奶牛的距离),那么问题实质上是将 n 个点分成 k 组,组内的点之间没有距离,组间元素会有距离,问如何分组,可以使得组间距离最小值 M 最大,并求最大的 M。
- 分析:
- 可以先考虑 k = n 时的情形,那么显然每组中只有一个元素,那么 M 即为对应最小生成树中边权的最小值(实际上也是所有距离中的最小值)。
- 思考 k = n - 1 时的情形,需要把两个点合并成一组,要想使得 M 尽可能地大,应该合并哪两个点?应该选择最小生成树中边权最小的那条边对应的两个点,将两个点合并成一个组,那么就能在最小生成树上去掉这条边权最小的边,M 就变成了原本最小生成树中边权第二小的值。以此类推,每次可以去掉一条最小生成树中边权最小的边,使得 M 尽可能地大。
- 需要去掉多少条边?初始的时候默认分成 n 组,每次去掉一条边(合并两点为一组),组数减少 1,最终的组数是 k 组,因此需要减少 n - k 条边。
- 如果将所有最小生成树上边的权值从小到大排序,那么第 n - k + 1 条边的权值即是答案(前 n - k 条边已经被减去了)
- 综上所述,先对 n 个点的图求一次最小生成树,并将每一条边加入到一个数组中,从小到大排序后,第 n - k + 1 小的边(也是第 k - 1 大的边)的权值即是答案。
-
易错点:
- 由于两点间的距离可能很大,需要使用 long long 类型。
「NOIP2013」货车运输 (easy version)
- 详见课本 【例10.2】货物运输