更快的单源最短路

试图翻译论文。

以下复杂度基于稀疏图,即 \(n,m\) 同阶。

对于无向图,单源最短路的最快时间复杂度是 \(O(n\sqrt{\log n\log\log n})\),对于有向图,单源最短路的最快时间复杂度是前几天刚提出的 \(O(n\log^{\frac{2}{3}}n)\),均由 交叉信息院段然研究组 提出。


先来看看无向图。论文链接

第一步是对图三度化。

考虑一个结点的邻居结点,把这个结点变成一个 \(d\) 元环,其中 \(d\) 为结点的度数,环上的边权为 \(0\),环上的每个点连向一个原先的点的邻居结点。

这样点数还是 \(O(n)\) 的。

我们考虑,我们有一种这样的算法——先随机撒点跑 dij(现在及以后出现的 dij 均需要使用斐波那契堆优化),每次 dij 整体维护这个点表示的块的最短路,有点类似树分块的感觉,不过这里是图分块。

考虑我们可以随机的每 \(x\) 个点加一个,即加入整点集的概率为 \(\frac{1}{x}\)

然后怎么图分块呢?有一个很显然的想法就是散点直接加入离整点最近的点。事实上确实用的是这个。定义 \(belong(u)\)\(u\) 所属的整点,\(Bundle(u)\) 表示整点 \(u\) 所对应的块。

我们再对于每一个结点定义邻域,\(N(u,w)\) 为所有 \(dis(u,v)\le w\)\(v\)。定义一个点的球 \(Ball(u)\) 表示 \(N(u,dis(u,belong(u)))\)(注意 \(belong(u)\)\(u\) 都在 \(Ball(u)\) 中)。

目前的最大目标是先把每个结点的球求出来。考虑对于每个点跑一次 dij,直到第一个整点被堆弹出。那么这个整点就是 \(belong(u)\),整点之前所有被弹出的点构成的集合就是 \(Ball(u)\)

考虑时间复杂度,\(|Ball(u)|\) 的期望是 \(O(x)\) 的,那每次时间复杂度期望就是 \(x\log x\),最多 \(O(n)\) 个点跑,那么时间复杂度就是 \(O(nx\log x)\)

这样还可以顺便把 \(u\) 和所有 \(Ball(u)\) 中元素的距离求出来。

接下来是正片了。

考虑用以下流程跑最短路(其中将结点 \(u\)\(w\) 松弛表示 \(dis(s,u)\)\(w\) 取最小值)。

最开始,将所有整点插入(斐波那契)堆中。将和 \(s\) 距离为 \(d\) 的堆顶 \(u\) 弹出去的时候,依次执行如下操作:

  1. 枚举 \(u\) 所对应的块中结点 \(v\),对于每一个 \(Ball(v)\) 中的元素 \(w\not =v\),将 \(v\)\(dis(s,w)+dis(w,v)\) 松弛。注意 \(u\)\(w\) 中的一员。在对于每一个 \(Ball(v)\) 中的元素 \(w\not =u\),再枚举和 \(w\) 相邻的一条通向 \(x\) 边权为 \(y\) 的边,用 \(dis(s,x)+y+dis(w,v)\) 松弛 \(v\)
  2. 然后,枚举与 \(v\) 相邻的一条通向 \(x\) 边权为 \(y\) 的边,用 \(dis(x,v)+y\) 松弛 \(x\),类似的,枚举每一个 \(Ball(v)\) 中的元素 \(w\not =u,v\),用 \(dis(x,v)+dis(v,w)\) 松弛 \(w\)

对于以上两步,每次松弛散点 \(u\) 的时候,同时用 \(dis(s,u)+dis(u,belong(u))\) 松弛 \(belong(u)\)

复杂度分析留给读者作为练习,可以证明这部分复杂度是 \(O(\frac{n\log n}{x}+nx)\) 的。

和求球加在一起是 \(O(\frac{n\log n}{x}+nx\log x)\),取 \(x=\sqrt{\frac{\log n}{\log\log n}}\) 就可以做到 \(O(n\sqrt{\log n\log\log n})\) 了。


现在去看有向图。论文链接

这个做法是一个确定性做法,用到无向图上也是目前最快的确定性算法

论文还没读懂,全英太困难了,别催了别催了[流泪]。

posted @ 2025-08-19 22:11  梦幻の蝶  阅读(151)  评论(0)    收藏  举报