P3645 [APIO2015] 雅加达的摩天楼
根号分治,跳跃能力小于等于 \(\sqrt n\) 的 doge 不同跳跃能力数量有限,大于 \(\sqrt n\) 的 doge 能跳到的位置有限。
所以状态只有 \(O((N+M)\sqrt N)\) 种,可以接受,数据范围较小用 bitset
判断比较方便。
然后有一种神奇的东西叫 01BFS,能 \(O(V+E)\) 解决边权仅为 \(0\) 和 \(1\) 的最短路问题:当选择一条权值为 \(0\) 的边时,塞入队首;当选择一条权值为 \(1\) 的点时,塞入队尾。这样就能时刻保证路径长度的单调性。
值得注意的是,同一座摩天楼可能会在不同的跳跃能力下多次入队,但传递消息是不需要花费跳跃次数的。所以一座摩天楼上的 doge 只需要接收第一次跳过来的 doge 的消息,后续就不用再次接收了,否则时间复杂度就会变成 \(O(M^2)\)。
还有一个极易忽略的点(建议去 UOJ 上交一发),01BFS 要在出队时打标记而不是入队时,因为第一次可能是塞入队尾,后面塞入队首可能更优。这样时间复杂度并不会改变,因为仅仅是在 \(O(E)\) 的前提下多塞入了一次点,并不会进行拓展。