AT274の技術だったりなかったり

あっとのTECH LOG

競プロのこととか技術のこととか。たまに日常を書きます。

ABC148 F - Playing Tag on Tree

問題原文

atcoder.jp

問題要旨

木の上で高橋くんと青木くんが鬼ごっこをする。高橋くんは逃げる側、青木くんは逃げる側。
高橋くんから、「相手と同じ頂点にいたらゲーム終了。そうでなければ1手移動。」を繰り返す。
高橋くんは出来るだけ捕まらないように、青木くんは出来るだけ早く捕まえられるように行動する時、青木くんは何回移動することになるか?

考えるべきこと

高橋くんは、「高橋くんが捕まらずにたどり着ける頂点のうち、青木くんから最も遠いもの」を目指せば良い

視点を高橋くんから青木くんに持っていけばわかる。
高橋くんから最も遠い頂点が、青木くんにとって最も遠い頂点でないことに注意。 視点が高橋くんのままだと詰まるりそう。

ある頂点を経由して、高橋くんにとっての理想の頂点を目指す時、途中で捕まらないか?

ある頂点  x が存在して、 高橋くんのいる頂点を u, 青木くんがいる頂点を  v とするとき、  dist(u, x) \lt dist(v, x) ならば、頂点  x からさらに潜る?頂点たちへは、高橋くんの方が必ず早くたどり着けるから大丈夫。
f:id:AT274:20191225215502p:plain

最後に青木くんが追いついて終了?高橋くんが青木くんに向かって行って終了?

落ち着いて図を書けば、実はどちらのターンで終わるかは関係ないことがわかる。

高橋くんが向かって行って終了のパターン
f:id:AT274:20191225215951p:plain

青木くんが追いついて終了のパターン
f:id:AT274:20191225220311p:plain

共通しているのは、「高橋くんが追いつかれるのは行き止まりに追い詰められた時」で、「捕まる場所は葉の親」だということ。

結局

頂点 u と 頂点 v それぞれについて、 全頂点への距離を計算し、  dist(u, x) \lt dist(v, x) を満たすようなもののうち、最大の   dist(v, x) - 1 が答えになる。

実装

N, u, v = map(int, input().split())
u, v = u - 1, v - 1
T = [[] for i in range(N)]
for i in range(N - 1):
    a, b = map(int, input().split())
    a, b = a - 1, b - 1
    T[a].append([b, 1])
    T[b].append([a, 1])

# 最短距離が求められればなんでもいい
U_dist = dijkstra(T, u)
V_dist = dijkstra(T, v)
 
ans_candidates = [dv for du, dv in zip(U_dist, V_dist) if du < dv]
print(max(ans_candidates) - 1)

学び

  • 一人のプレイヤーの視点にこだわりすぎないようにしよう
  • 落ち着いて図を書こう

類題さん。。。。
atcoder.jp