图论题解
图论
A. 铲雪车
- 此题要求从起点开始遍历每条边,然后回到起点,虽然没说不能重复经过某条边,但要求花的时间最少,也就间接隐含能不重复走边就不重复。
- 但题目都给出了道路是双车道,那明显就是一个欧拉图,题目没要求求路径,所以我们只要求出所有边之和乘上2即可。
- 注意:
- 要求的是精确到分钟,所以我们要把速度换算成 米/分钟
B. 骑马修栅栏
- 此题要求每个栅栏恰好经过一次,而且保证有解,显然是一个欧拉图或半欧拉图。
- 但注意此题有重边,而每条重边都必须走一遍,所以如果用临界矩阵记录不能用
a[i][j]=1
表示i,j
连通通,而应用a[i][j]=cnt
表示i,j
间有多少条重边 - 因为要输出路径,而且需要按字典序输出,所以边表不适合,所以只能用邻接矩阵记录。
C. 最短路径
- 裸裸的最短路,只是需要注意精度和数据范围。
D. 医院设置
- 此题最直接的方法是把分别把每一个点当作医院,然后求出距离和,然后看那个点的距离和最小
- 所以我们要求出任意两点间的距离,数据规模较小,显然
floyd
正好 - 假设节点数较大,我们该如何解决,我们有更好的方法吗?
E. 奶牛跨栏
- 题意:一个
n<=300
个点m<=25000
条边的有向图,部分点间单向可达,边权为最大高度。 - 读懂题意就能明白做法,显然是一个最短路,只是松弛维护的不是距离而是高度,决策是使高度尽量小。
F. 最小花费
- 方法一:
- 此题很容易想到,银行当节点,1-手续比率 为权值,然后决策为乘法,求最长路即可。
- 但我们所学的算法均是解决最短路问题,不管是迭代还是贪心,均只能求最短路,因为一旦图中存在正权环,必然会无穷松弛,不存在最长路。
- 但此题可以,因为权值为
0~1
之间的小数,我们的决策为乘法,所以我们在逐步相乘的过程中,值会越来越小,此时如果求最短路反而不行,因为可能出现无线松弛,而最长路则不会。 - 方法二:
- 我们可以对问题稍作变化,边权为 1/(1-手续比率 为权值),然后就可以正常做最短路。
G. 信使
- 裸的不能再裸的最短路,再解释是侮辱你们的智商。
H. 香甜的黄油
- 此题乃D.医院设置的同胞兄弟,不会看兄弟!
I. 学校选址
- 悄悄告诉你,此乃D、H弟弟!
J. 连接格点
- 题意:\(m \times n\) 的二维矩阵,某些点间已连接,抽象成图就是一个离散的图,我们需要加边,让整个图连通,加边的代价是纵向代价为1,横向代价为2
- 并查集是一个非常简单高效的判断图的连通性的算法,但我们如何吧矩阵的点变成一维的点呢?
- 比如
i,j
表示第i
行,第j
列的点,转成一维x
,显然有:x=(i-1)*n+j
- 在数据读入时我们即可通过并查集把图分成若干个集合。然后再把这些集合通过建边合并起来
- 因为纵向建边比横向费用低,所以我们优先纵向建边,即扫描二维矩阵,如果上下两个节点不在一个集合,则花费1建边,并合并。
- 然后再扫描此二维矩阵,左右两点如果不在一个集合,则建费用为2的边。两遍扫描,整个图即为连通,此种建边必然费用最小。
- 比如
K. 最优布线问题
- 题意:
n
个点,任意两点可以相连并有权值,求以最小代价让图成为连通图。 - 只需要连通,显然建的边越少越好,边权和越小越好,这不就是一个裸裸的最小生成树吗!
L. 局域网
- K题姊妹!!!
M. 繁忙的都市
- 此题条件1,2实际上就是要求我们求最小生成树,因为连通图最小边必然会是一颗树。
- 条件3告诉我们决策不是让权值和最小,而是求最小生成树的最大边,显然克鲁斯卡尔建完树后加的最后一条边即为max,s不用算,必然为n-1。
N. 联络员
- 此题再最小生成树的基本模型上稍加了点限制,及有一些边必选。
- 这有什么好说的,必选边先做并查集,然后从小到大对边排序,然后逐一判断,类似克鲁斯卡尔加边,直到整图连通。
O. 挖水井
- 此题是一道非常经典的板子题,很容易看出就是要求最小生成树,但困难的是如果在某个点选择挖井的话,因为并没有建边,所以无法判断图的连通性。如果我们能把挖井的费用也变成一条边的话此题就好解决了。
- 我们可以建一个
1~n
之外的一个虚点,比如0
或n+1
,然后对这1~n
每个点和这个虚点建一条边,边权为挖井的费用。这样题就变成了n+1
个点的图,裸裸的最小生成树了! - 此模型大家一定牢记,再以后很多类似的处理方法。
P. 最小差值生成树
- 这道题实际没那么简单,但数据很弱就变的很简单了,简单的做法是什么呢?
- 我们把边按边权从小到大进行排序,排序后我们依次枚举最小的边,从这条边开始做最小生成树,然后求出差值,不停的枚举最小边直到剩下的边不足
n-1
,或无法产生生成树为止。
Q. 安慰奶牛
- 此题很好,唯一的败笔就是描述翻译的模糊不清,这也是我们信奥的特点,哎,一言难尽!
- 说白了,此题就是要我们把图变成一颗树,因为要保留最少的边且连通嘛,但是否是一颗以边权为排序依据的最小生成树呢?也不是,因为除了边有权值,每个点也有权值。
- 我们再分析一下,在保证边最少的情况下我们要遍历每个点至少一次,然后再回到起点。这不就是图的遍历嘛,显然图的遍历每一条边需要走两边,去一遍、返回一遍,来和去的时间代价一样,均为起点权值+边权+终点权值。
- 分析到这一步,答案就昭然若揭了嘛!我们就以(起点权值+边权+终点权值)*2建边,然后做最小生成树不就行了吗?如此简单!
- 不过我们还没有解决起点的问题,我们稍微模拟下就能很容易得出,在遍历整颗树最后回到起点,起点会多访问一次,显然嘛,我们就选权值最小的点作为起点即可。
- 此题除了描述有点信奥外,很好的一道题,好好领悟!
R. 公路建设
- 此题跟P有点类似,很多同学直接就没加一条边做一遍最小生成树,太暴力了,不过对此时的你们和此题的数据范围来说,的确也行了,不过我们还可以加一些优化。
- 优化一:前
n-2
条边可以直接输出0
- 优化二:可以边加边,边用并查集判断图的连通性,不连通直接输
0
- 优化三:在做克鲁斯卡尔时,不用没加一条边就排一次序,因为加边时,前面的边已经有序,所以用二分差,插入当前边即可。
hzoi