競技プログラミングのためのF#入門
1 2 3 4 |
|
練習も兼ねて(破壊的な)Union-Findを簡易実装して対応します. 提出された解答を眺めていたら, 少なくともRustではpetgraph crateがあってAtCoderでも使えるようです.
クラスとしての実装はUnionFind.fsxに置いてあります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
直接的な友達・ブロックの隣接行列を作りながらUnion-Find木を作ります. 隣接行列は.NETのResizeArray()
のAdd
でゴリゴリと破壊的に作ります.
1 2 3 4 5 6 7 8 |
|
Fa
が友達(friends), Ba
がブロックの配列です. 入力のXa
の処理の中でunite a b
をかませてUnion-Find木を作っています.
公式解説通り次の量を計算します.
1 2 3 |
|
各頂点i
に対して連結成分のサイズはsize i
, 友達関係にある頂点j
の数はFa.[i].Count
で計算できます. ブロック関係にある頂点j
の数はUnion-Find
のfind
を使って次の処理で計算できます.
1 |
|
あとは各頂点ごとの計算を次のようにArray.map
で処理します.
1 2 3 4 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|