前言
没错,又是有同学提起这个问题我就来写一个的。他们的考试中有这么两问:一问是说求 n n n 个点的图中给定两点间的路径最大值最小是多少,要求时间复杂度是不超过 O ( n 2 ) O(n^2) O(n2) ;一问是说要对任意两点求出它们之间间的路径最大值最小是多少,要求时间复杂度不超过 O ( n 3 ) O(n^3) O(n3) 。
下面就简单说一下这两个问题。
第一问
我们简单想一下这实际上就是瓶颈路径的定义,显而易见的我们可以使用最小生成树去解决这个问题。但是直接写好像是 O ( m log m ) O(m\log{m}) O(mlogm) 的,比点数平方大,不是很能接受。同时诸如各种最短路算法其实也都是超过这个级别的。
这时候就需要返璞归真或者上一些更暴力的科技了。
一种做法是我们直接写一个暴力的prim算法。每次我们直接暴力的去扫一次剩下点中距离当前块最小的那个,然后加进来,更新其他的点。这样的话我们会有 O ( n ) O(n) O(n) 次扫描所有点,以及每条边会在有端点被加进来的时候使用一次,总复杂度就是 O ( n 2 + m ) O(n^2+m) O(n2+m) 的。
另外一种做法就是我们直接把二叉堆换成fib堆,这样复杂度就直接变成 O ( n log n + m ) O(n\log{n}+m) O(nlogn+m) 的了,非常的方便。
第二问
实际上这个还更简单了,因为我们求出来最小生成树之后,只需要更换根节点遍历 n n n 次就做完了,总复杂度还是 O ( n 2 ) O(n^2) O(n2) 的。当然,由于时间宽裕了,其实跑一次全源最短路实际上也是可以的。
一些闲话
其实这个题难度并不高,想不到的原因可能是老师没讲到过最小生成树是瓶颈生成树这个事情,以及对暴力算法的复杂度不明晰。可能前者是主因吧。