buyoh.hateblo.jp

残念な競技プログラミング参加者による学習記録

AtCoder Regular Contest 061 - E すぬけ君の地下鉄旅行 / Snuke's Subway Trip

解説と若干違っていたので

概要

https://beta.atcoder.jp/contests/arc061/tasks/arc061_c

鉄道会社の乗り換えを最小化せよ

かなり雑なブログ記事です

Hypergraph

ハイパーグラフとは,ハイパー辺と頂点から構成されるグラフのようなもの. 通常の辺は2つの頂点に接続するが,ハイパー辺は1つ以上の頂点に接続する.

考察

1

ある鉄道会社の路線が連結でないとき,それぞれの連結成分は異なる鉄道会社である,と解釈しても答えは変わらない.

よって,ある鉄道会社の路線が連結でないときは,別の鉄道会社として新たに番号を割り当てる.(適当に実装すると最悪時間O(M2)になるっぽいので要考察)

2

それぞれの鉄道会社の辺集合を,ハイパー辺に置き換える. 具体的には,鉄道会社の辺集合が接続する頂点を全て列挙して,列挙した頂点に接続するハイパー辺に置き換える.

辺コスト1の,ハイパーグラフ上の最短経路問題になる.

3

辺コスト1の,ハイパーグラフ上の最短経路問題を解くために,ハイパーじゃないグラフに構築し直して,最短経路問題を解く.

グラフ→ハイパーグラフ→グラフの変換ですね.

ハイパー辺をスターに置き換える.つまり,ハイパー辺ごとに頂点を作成して,ハイパー辺が接続する頂点と作成した頂点を接続させる.

このグラフに対して最短経路問題を解くと,辺コスト2のハイパーグラフ上の最短経路のコストが得られる.2で割って出力.

実装

1の実装

僕はこんな感じ.各鉄道会社について,次の処理を行う.

  1. Unionfindを初期化する.
  2. 鉄道会社が持つ辺(路線)について,Unionfindでつなげていく.
  3. 連結成分の個数が求まるので,空のハイパー辺を個数作る.
  4. 出現した各頂点(鉄道会社が持つ駅)について,頂点が属する連結成分を調べて,対応するハイパー辺に頂点を追加する.

普通Unionfindはvectorで実装されていて,初期化にO(N)かかってしまうので,mapで実装し直す.時間計算量はO(Nlogc N)ぐらい.cは2から4ぐらい.

最初はdfsだったんですが,落ちた.撃墜ケースも分からず.

提出

https://beta.atcoder.jp/contests/arc061/submissions/2936079