题目大意
hdu oj已挂,就不写代码了
有一个 n 个点 m 条边的有向带边权图。现在给你 k 个点,
问 k 个点中最近的点对距离。
n, m, k <= 100000
题目思路
思考一个问题:
给定两个点集A和B,求A中的点到B中的点的最近距离。
新建一个源点S,往A中的所有点连一条边权为0的边。
新建一个汇点T,B中的所有点向T都连一条边权为0的边。
求S到T的最短路就是答案,即建立两个超级源点
那么只需要把 k 个点的集合分成两半,然后用上述做法求出一部分答案。
如何保证每个点对(i, j)都存在一次划分使得 i 和 j 分别处于两个不同的集合?
因为点i和点j的下标分别是i和j。
由于i不等于j,所以在i和j的二进制表达式中,一定有一位不同。
那么我们只要划分log n次,每次依据下标的二进制中第i位是0还是1,
分成两个集合。跑一次最短路。
这样就能保证,任意一对(i,j),都存在一次划分,使得它们属于不同
的集合。也就相当于考虑了每一种情况。
时间复杂度:O((n + m) log2 n)
感觉非常的妙,妙不可言