競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 148F

ABC148F

\(v \in V\) をとる. 高橋君が最初に居た座標から \(v\) への距離を \(dis_{0}(v)\) とおく. 同様に青木君版を \(dis_{1}(v)\) とおく.
高橋君が \(v\) に到達可能であることは, 青木君よりも先に到達可能であることと同値. すわなち, \(dis_{0}(v) < dis_{1}(v)\) と同値.
このとき,青木君の移動距離は \(dis_{1}(v) -1\). なぜなら,ゲーム終了は常に葉の親だから. これは,ゲーム終了の直前に高橋君が葉に居ることから分かる. 葉に居ない場合は,青木君の居ない側の葉に向かって逃げることで ゲームを長引かせることが出来るから. この考察により,path の長さによる偶奇で場合分けが不要になる. 逆に,これが思いつかなければ偶奇で場合分けすれば何とかなる.

以上から,
\(for \ v \in V\) s.t. \(dis_{0}(v) < dis_{1}(v)\)
 chmax(ans, dis_{1}(v) - 1 )
で答えが求まる.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n, x, y ; cin >> n >>  x >> y;
  --x,--y;
  vvll to(n);
  rep(i,n-1){
    ll a,b; cin >> a >> b;
    --a, --b;
    to[a].push_back(b);
    to[b].push_back(a);
  }
 
  auto dfs = [&](auto dfs, ll cu, ll pa, ll d, vll &v) -> void {
    v[cu] = d;
    for(auto ne: to[cu]) if(ne != pa){
      dfs(dfs, ne, cu, d + 1, v);
    }
  };

  vvll dis(2, vll(n, -1));
  dfs(dfs, x, -1, 0, dis[0]);
  dfs(dfs, y, -1, 0, dis[1]);

  vll a(n);
  ll ans = -1;
  rep(i,n){
    if(dis[0][i] < dis[1][i]){
      chmax(ans, dis[1][i]-1);
    }
  }
  cout << ans << endl;
 
  return 0;
}