随机算法多好啊。
传送门
题解
对于这题,一开始能比较容易地想到一个乱搞的做法:
将$k$个关键点随机分成两半,建立超级源点向其中一半的所有点建边权为$0$的边,再从另一半向超级汇点建边权为$0$的边。
然后用Dijkstra求出源点到汇点的最短路,取每次求解出最短路的最小值为答案。
这样一次求出最优解的概率为$\frac{1}{4}$。
但是如果我们重复以上操作20次,那么求出最优解的概率为$1-(\frac{3}{4})^{20}\approx99.7\%$。
这样AC的概率其实已近非常高了,如果能优化常数然后增大重复次数,那么AC的概率还可以进一步提高。
其实如果想到了上面乱搞的做法,离正解也很近了。
我们可以根据关键点编号在二进制中第$i$位上的数字来对这$k$个关键点进行分组,为$0$的分在一组,为$1$的分在另一组。然后按照上面的方式建图求最短路。
假设最优解中的起点为$u$,终点为$v$,那么它们编号在二进制中至少有一位不同,所以它们必定会在某一次分组中被分在了不同的组,从而求解出了答案。
时间复杂度$O(nlog^2n )$。
注意由于图是有向的,所以每枚举到二进制中的一位时应进行两次分组。
代码
1 |
|