IOI2018 高速公路收费

来补一下代码,太鸽了。。。。。

https://www.cnblogs.com/Dance-Of-Faith/p/9657606.html

考虑一条链怎么做:直接二分。

一棵树怎么做:

我的第一想法是边分,找一条边 \(u,v\) 使得 \(S,T\) 在两边,然后在 \(u,v\) 向外 bfs 。

二分 bfs 序,将距离最远的一圈点变成最短路必须经过 B ,剩下的点可以只经过 A .

容易2次二分出 \(S,T\) 的位置。

需要找到这条边,边分是不太行的,可以直接二分边的列表,把 \([1,mid]\) 的边变成 B check一下距离有没有变大。

(要初始查一下全 A 的距离)查询次数 \(1+\lceil\log(130000)\rceil + \max(\lceil \log(i) \rceil + \lceil \log(90000-i) \rceil) \le 17 + 16 + 16 + 1 = 50\)

(如果要卡到 \(51\) 次,需要 \(32769+65537>90000\) 个点,所以数据范围是卡好的)


考虑图怎么做:

似乎很难做,但是根据上面的思路,如果找到一条在 \(S,T\) 路径上的边就迎刃而解。

这条边依然可以在边列表中二分。二分某个 [1,mid] 变成 B 不会增加,[1,mid+1] 变成 B 增加了就可以了。

其实这边隐含了一个优化。如果是二分了一个点出来的话,后两次二分就各需要 \(\log(90000)\) 次,就会超限。

$$\Huge \text{Goodbye OI}$$
原文地址:https://www.cnblogs.com/Rainbowsjy/p/15769196.html