最短路树 科普笔记

一个非常冷门的知识点(大概吧)

基础定义

定义:一个 n n n 个点, m m m 条边的无向图,最短路树是图上的一棵生成树,以一个节点 x x x 为根,满足对于任意 i ( 1 ≤ i ≤ n , i ≠ x ) i(1\le i\le n,i\neq x) i(1in,i=x),树上两点最短路的距离等于原图两点最短路距离。

性质:第一个即是其定义,第二个是我这个民科自己想的,不一定对:对于两个节点 u , v u,v u,v 满足同属于最短路树上的一条链,那么二者原图上的最短路就是树上两点到根节点距离之差。(证明:考虑反证,若两点有更短的距离,那么肯定会用这个距离去更新深度更深的节点)。

如何求出:考虑 dijkstra 的过程,当使用一个节点 u u u 更新另一个节点 v v v 时, ( u , v ) (u,v) (u,v) 显然目前来说在最短路树中,所以记录最后更新每个节点 i i i f a i fa_i fai,则 ( f a i , i ) (fa_i,i) (fai,i) 是最短路树上一条边这很显然,不用证了

如何求出边权和最小最短路径树:其实只需要把 dis[v]>dis[u]+e[i].w 改成 dis[v]>=dis[u]+e[i].w 即可。为什么?

证明:我们为了使得边权和最小,我们就想尽量使得不同路径的并集最大,即是想要 d i s u dis_u disu 最大,从 dijkstra 的优先队列中取出的 d i s u dis_u disu 必然单调递增,这个结论反证法自证不难。如果 dis[v]==dis[u]+e[i].w`,则后来者肯定更优。

例题

[USACO09JAN]Safe Travel G

题意简述:给定一张有 n n n 个节点, m m m 条边的无向图,对于任意的 i i i 2 ≤ i ≤ n 2\le i\le n 2in),请求出在不经过原来 1 1 1 节点到 i i i 节点最短路上最后一条边的前提下, 1 1 1 节点到 i i i 节点的最短路。

很容易想到最短路树,题目即是要对于每个节点 u u u 和其父亲节点 v v v ,找到 u u u 子树内一点 x x x 使得 d i s v + w ( v , x ) + d i s u − d i s x dis_v+w(v,x)+dis_u-dis_x disv+w(v,x)+disudisx 最小。

回想到不久前才做(咕掉)的 CF827D Best Edge Weight,会发现这两题竟是如此的相似,对于一条非最短路树边 ( u , v ) (u,v) (u,v) 都可以整一个树上覆盖问题,唯一的问题是,这次我们要覆盖的东西变成了上文所述的 d i s v + w ( v , x ) + d i s u − d i s x dis_v+w(v,x)+dis_u-dis_x disv+w(v,x)+disudisx,如果还是按边权排序会出大问题,那怎么办呢?就按 d i s v + w ( v , x ) + d i s u dis_v+w(v,x)+dis_u disv+w(v,x)+disu 不就完了吗。

おすすめ

転載: blog.csdn.net/cryozwq/article/details/120047897
おすすめ