はじめに
ダブリングを理解するために記事を書きました
間違っていたらごめんなさい
競プロでの活用を目的としています
ダブリング を使う時
グラフで自分の位置から、x個前の親が誰なのか知りたいよ〜な時など
(私が直面し、学ぶきっかけとなった内容です)
他にもあります・・・
どんな感じ?
愚直でやると、一つ一つ階段を登っていく感じだけど、ダブリング活用すると2段抜かし、4段抜かしみたいに登る段の回数が少なくて済むよ〜
電車で例えると、
愚直・・・・・・・→ 普通電車 各駅止まりますよ〜
ダブリング・・→ 特急電車 飛ばす飛ばす時々止まる
やる事
① 準備・前計算:参照用のテーブル作り
② 参照用のテーブル(parent)を利用して、欲しい値を得る
具体例見ながら考えよう!
例)参考を見ながら自分で作ってみたグラフと参照用のテーブル
① 準備・前計算:参照用のテーブル作り
自分の表の前行や他列を参照して、1個前、2個前,4個前・・・を見るような表を作っていく
* 2次元配列を作る
parent[][]
・・・parent[親等・深さ][自分・頂点]
↓
* 0行目:各頂点(v)の親を入れる
parent[0][v] = 親
根の親は-1
↓
* 1行目以降k
行目:parent[k][v]
←自分
・同じ列である頂点(v)のk-1行目(表のk行目の1つ上)の値を見る
pv = parent[k-1][v]
・その値の頂点(pv)のk-1行目の値を見る
xv = parent[k-1][pv]
・その値の頂点(xv)を自分の所の値として入れるパクパク
parent[k][v] = xv
これの繰り返しで表を埋めて完成!
(見えづらいので表拡大)
parent[k][v]
を埋めたい!埋める値を見つけるよ!
② 参照用のテーブル(parent)を利用して、欲しい値を得る
自分(v)のx
個前の親が知りたい
↓
x
の2進数を求める(二進展開と表現すると知った)
1のビットが立っている所をki
とする
↓
ki
がある分繰り返す
頂点(v)の ki
行目を見る
pi = parent[ki][v]
pi = parent[ki][pi]
← 複数ある場合
↓
頂点(pi)の,0行目(xp)を見ると、自分(v)のx
個前の親(xp)が求まる
xp = parent[0][pi]
例)
愚直にやると知りたい親の頂点まで一つ一つ数えて遡っていかなければならないけど、このようにダブリングでやると、二進展開した時の立ってる1の数の個数分遡るだけでよくなるので計算量が減らせる
ちなみに、ダブリングが2回に対して、愚直にやると9回遷移が必要
おわり
読んでくださりありがとうございます。
問題の中の一部に対して、解説を読みながら調べて学んでいたので、コードは省略します。
こちらで学ばせていただきました
satanic0258さんありがとうございました