2020年11月20日金曜日

CS Academy Round #83 - Firestarter

着火クエリ(Ti,Ai,Bi,Xi)(T_i, A_i, B_i, X_i)に対して新しい頂点ViV_iを導入し、辺{Ai,Bi}\{A_i, B_i\}を分割して長さXiX_iの辺{Ai,Vi}\{A_i, V_i\}と長さLXiL-X_iの辺{Vi,Bi}\{V_i, B_i\}を張る。ひとつの辺上に複数の着火が起こる場合には、3つ以上に分割する。こうしてできたグラフ上で、各頂点に初めて火が到達する時間を求める。具体的には、ViV_iの距離をd[Vi]:=Tid[V_i] := T_iとセットして多点スタートのダイクストラをする。(形式的には、大頂点SSを導入して各ViV_iSSの間に長さTiT_iの辺があると考えるのがよさそう。)

こうすると、頂点vvに初めて火が到達する時間がd[v]d[v]に入ることになる。ただ、欲しいのはすべての辺が燃えきる時間なので、maxd[v]\max d[v]は答えにならない。長さllの辺{u,v}\{u, v\}が燃えきる時刻をttとすると(td[u])+(td[v])=l(t-d[u])+(t-d[v]) = lなので、t=(l+d[u]+d[v])/2t = (l + d[u]+d[v])/2と求まる。この最大値を答えとすればよい。


時刻を決め打って二分探索をやってしまって、さすがにTLEだった。