「学习笔记」分层图最短路

分层图最短路

偶然间看到了这个,正好没学过,感觉挺有意思的,于是就顺手写个了博客。

定义

顾名思义,“分层图最短路”就是在分层图上跑最短路。

模型

在图上,有k次决策,问起点与终点之间的最短路径。

k个决策不会影响图的结构,只会影响当前的代价或状态。

做法

一般有两种做法:

  • 第一个方法:建 $k+1$ 的分层图。

  • 第二个方法:多开一维的数组记录决策信息。

方法一

  • 对于同一层的图,每一层都按原图建边。

  • 对于相邻两层的图,若原图中从 $u$ 到 $v$ 有一条边,那么就从 $u$ 到下一层对应的 $v$ 连一条边,从 $v$ 到下一层的 $u$ 也连一条。边的权值取决于决策内容。

这样我们就通过建图模拟了 $k$ 次决策。

具体可参考下面这张图(引用于cyhyyds的博客)。

具体的建边过程如下:

for(int j=0;j<=k;j++){
    //同一层建边
    add_edge(u+j*n,v+j*n,w);
    add_edge(v+j*n,u+j*n,w);

    //两层间建边
    add_edge(u+j*n,v+(j+1)*n,0);
    add_edge(v+j*n,u+(j+1)*n,0);
}

方法二

首先可以在原来的数组上多加一维来记录决策信息:

  • $dis[i][j]$ 表示到达点 $i$ 进行了 $j$ 次决策时的最短路。
  • $vis[i][j]$ 表示到达点 $i$ 进行了 $j$ 次决策时点 $i$ 是否访问过。

状态转移($w$ 为边权):

  • $dis[v][k]=min(dis[v][k],dis[u][k]+w)$
  • 可以进行决策时:$dis[v][k]=min(dis[v][k],dis[u][k-1]+w)$

在这种方法中,数组记录的进行了 $j$ 次决策,实际上也可以看做是在方法一中的图上到达了第 $j$ 层,两者是等价的,复杂度都为 $O(mklog(mk))$ 。

个人比较喜欢第一种,毕竟多加几句建个图直接套模板谁不喜欢呢

练习

P4568 [JLOI2011] 飞行路线

板子题。因为次数不一定要用完,所以答案要从每层终点的答案里取最小值。

P2939 [USACO09FEB]Revamping Trails G

双倍经验。

P1948 [USACO08JAN]Telephone Lines S

三倍经验?注意题目中的花费是路径边权最大值,要改一下最短路模板。

P4822 [BJWC2012]冻结

层之间的边权为原边权一半。

P1073 [NOIP2009 提高组] 最优贸易

在这道题中的决策是买入或卖出或不买。只要建三层就够了,第一层到第二层代表买入,边权为 $-w$ ;第二层到第三次代表卖出,边权为 $w$ 。每一层内边权均为 0 。


本篇参考:

分层图最短路 – Eleven谦 – 博客园

「学习笔记」分层图最短路 – cyhyyds – 博客园

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇