かんプリンの学習記録

勉強したことについてメモしています. 主に競技プログラミングの問題の解説やってます.

ABC218 F - Blocked Roads

公式解説より効率の良いアルゴリズムの説明です.

問題はこちら

問題概要

{N}頂点{M}辺の有向グラフが与えられる.各{i(1\leq i\leq M)}について,辺{i}のみ通れないときの頂点{1}から頂点{N}までの最短距離を求めよ.

{2\leq N\leq 400\\
1\leq M\leq N(N-1)}

解説

頂点{1}から頂点{N}までの最短経路を一つ求めます.明らかに,その最短経路上にない辺を消すときの答えは元のグラフの頂点{1}から頂点{N}までの最短距離と一致します.
例えば,下図のグラフにおいて,ある黒の辺を消しても赤の辺からなる最短経路が通れるままなので答えは元のグラフの最短距離になります.
最短経路に含まれる辺の数は高々{N-1}本なので,そのような辺ごとにその辺を消したグラフにおける最短距離を求めればいいです.一つの辺につきBFSで{O(N+M)}かかるので全体で{O(N(N+M))}でかかります.

f:id:kanpurin:20210913204907p:plain:w300

最短経路上のある辺{(u,v)}を消したグラフの最短距離は下図のような位置関係にある頂点{t}で「頂点{1}から頂点{t}を通って頂点{N}に行くまでの最短距離」のうち最小のものが答えとなります.

f:id:kanpurin:20210913222037p:plain:w300

このとき,{1\rightarrow L_t\rightarrow t\rightarrow R_t\rightarrow N}の順で通るとします.{L_t,R_t}{1\rightarrow L_t}{R_t\rightarrow N}は元のグラフの最短経路上の辺を通り,{L_t\rightarrow t\rightarrow R_t}は元のグラフの最短経路上の辺を通らないような頂点とします.各頂点{t}に対して{L_t,R_t}を計算しておくとこの問題は以下のような問題になります.

{O(N)}個の座標{T_i}および,{O(N)}個の区間{[L_j,R_j)}とその区間の重み{W_j}が与えられるので,各{T_i}に対して,{T_i}を含む区間の重みの最小値を求めよ.

これはSegment Treeやstd::setをを用いれば{O(N\log{N})}で解けます.

関連問題

重み変更クエリの問題https://codeforces.com/contest/1163/problem/F