不妨假设边的长度为
1
1
1,然后允许小数的出现。设
(
i
,
e
)
(i,e)
(i,e)表示从
i
i
i出发,油量为
e
e
e的状态。发现对于点
i
i
i,如果剩余能走的距离
e
≤
K
2
e\le \frac{K}{2}
e≤2K,并且到最近的关键点的距离
≤
e
\le e
≤e,事实上等价于从这个关键点出发。
基于上述这个事实,我们可以从每个关键点出发跑多源
B
F
S
BFS
BFS,然后处理出关键点之间的连通性,这可以用并查集维护。设从
u
u
u往
u
→
v
u\to v
u→v路径上走
K
2
\frac{K}{2}
2K到达的点为
u
′
u'
u′,可以证明从
u
u
u出发,
e
=
K
e=K
e=K能到达的有用的关键点和从
u
′
u'
u′出发,
e
=
K
2
e=\frac{K}{2}
e=2K能走到的关键点的集合相同。这样再套用前面的结论就做完了。但是如何证明呢?
让我们理论分析一波。设从
u
u
u到
v
v
v的路径中走了
x
x
x步,每个点到补给站的最短距离为
d
i
d_i
di,那么如果这个点对应的补给站有用的话应该满足
K
−
x
∈
[
d
i
,
K
−
d
i
]
K-x\in [d_i,K-d_i]
K−x∈[di,K−di],因此我们有
d
i
≤
K
2
d_i\le \frac{K}{2}
di≤2K。观察这个式子 ,如果
x
≤
K
2
x\le \frac{K}{2}
x≤2K那么
d
i
≤
x
d_i\le x
di≤x,因此从
u
′
u'
u′到关键点的距离为
K
2
−
x
+
d
i
≤
K
2
\frac{K}{2}-x+d_i\le \frac{K}{2}
2K−x+di≤2K;如果
x
>
K
2
x> \frac{K}{2}
x>2K那么
K
−
x
≥
d
i
K-x\ge d_i
K−x≥di,因此从
u
u
u到关键点的距离为
x
−
K
2
+
d
i
≤
K
2
x-\frac{K}{2}+d_i\le \frac{K}{2}
x−2K+di≤2K。这样就证完了。个人还是比较喜欢这样的代数证明的。
为避免出现
0.5
0.5
0.5的情况,可以考虑在每条边中间再添加一个虚点。
对于跨
L
C
A
LCA
LCA的情况,有一个非常巧妙的
trick
\text{trick}
trick可以学一下:如果到
L
C
A
LCA
LCA的距离
≥
K
2
\ge \frac{K}{2}
≥2K那么相当于从这个点跳
K
2
\frac{K}{2}
2K的距离,如果
<
K
2
<\frac{K}{2}
<2K那么相当于从另一个点跳
dist(u,v)
−
K
2
\text{dist(u,v)}-\frac{K}{2}
dist(u,v)−2K的距离。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」