足跡-sokuseki-

りかの日進月歩の記録

AOJ 2748 夏合宿の朝は早い

夏合宿の朝は早い | Aizu Online Judge

問題概要

 N 人それぞれの寝坊する確率と、連絡先を知っている人が与えられる。
起きた人が連絡先を知っている人すべてにモーニングコールをするとき、全員が起きられる確率を求めよ。

 1 \le N \le 100

解法

  • 誰にも起こしてもらえない人(誰にも連絡先を知られていない人)は自分で起きなければならない
  • ループしている人は、確率をまとめて1人として扱って良い

f:id:wk1080id:20180411112043p:plain

よって、連絡先を知っているという関係を有向辺にしてグラフで表現して、強連結成分(どの2頂点間も互いに行き来可能)を1つにまとめたグラフをつくり(強連結成分分解)、入次数が0の頂点の確率をかけてあげれば良い。


具体的な実装方針は

  • 強連結成分を調べるために、各頂点からdfsをしてあげて、互いに行き来可能な頂点同士をUnion-Find木で管理する(親が等しい頂点同士は同じ強連結成分に属する)
  • 各強連結成分ごとの確率を調べ、その強連結成分の入次数が0ならば、確率を答えにかけあわせる

計算量は、dfsパートは辺の数は高々  N^2 本なので O(N (N+ N^2)) 、Union-Find木を構成するパートは  O(N^2 ) 、強連結成分ごとの確率を求めるのと入次数が0かどうか調べるパートが O(N^3) なので、全体で O(N^3) になる。 N が小さいので間に合う。

http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2770535#1