Joeの精進記録

旧:競プロ練習記録

F. The Shortest Statement

F - The Shortest Statement

問題概要

 1 \le n \le 10^5頂点 m \ (m - n \le 20)辺の連結な重み付き無向グラフが与えられる。 (1 \le q \le 10^5)個のクエリに答えよ。 i番目のクエリでは頂点 u_i, v_i間の最短距離を答えよ。

考えたこと

木っぽいグラフが与えられるということなので、とりあえず木に場合について考えてみることにする。 木の場合はまんまLCAを使うことができます。具体的には

  1. 適当な1頂点を根として、根付き木を考える。この根から各頂点への最短距離をbfsでもして求めておく。
  2.  u_i, v_iに対して、これらのLCA O(\log n)で求め、それを w_iとおく。
  3.  u_i, v_i間の最短距離は、 d[u_i] - d[w_i] + d[v_i] - d[w_i]である。

次はこれをいまのグラフに拡張してみましょう。 グラフから適切に辺を k = m - n + 1本削除すると木になります。 削除された辺につながっている頂点の集合を Vとします。

元のグラフ上での2頂点間の最短経路はもちろん削除された辺を通る場合があります。そこで、削除された辺も含めた Vの 中の任意の2頂点間の距離をワーシャルフロイドで事前計算しておきます。

このとき、 u_i, v_i間の最短距離は次のように計算することができます。

  1. 最短距離を木上での最短距離で初期化します。
  2.  u_iから木上を通って w_j \in Vまでいき、そこから w_k \in Vに抜けて、  w_kから木上を通って v_iに行く経路をすべての j, kの組み合わせについて計算し、最短距離を更新する

定数倍が重めですが、 O(q\log n)でこの問題を解くことができました。