Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
HCPC勉強会 2016/01/07 1
HCPC勉強会 2016/01/07
グラフマスターに、俺はなる!
M2 鈴木 浩史
HCPC勉強会 2016/01/07 2
さらっと事前知識:グラフとはなんぞや
● グラフ
– 頂点(○ぽいやつ)を辺(線分)で結んだ図形
● example
– ○が人 → 友人関係の図
– ○が状態 → 状態遷移図
– 頂点や辺には値が付け...
HCPC勉強会 2016/01/07 3
さらっと事前知識:グラフの重要な用語
● 閉路
– ある頂点から開始して同じ辺を2度通らずに戻る路
● 連結
– 辺に向きがないとして全ての頂点が互いに行き来できる
● 木
– 閉路のない連結なグラフ
...
HCPC勉強会 2016/01/07 4
さらっと事前知識:DAG
● 非巡回有向グラフ(Directed Acyclic Graph : DAG)
– 辺に向きがあり閉路のないグラフ
● トポロジカル順序
– 各頂点が自身より若い頂点に辿りつ...
HCPC勉強会 2016/01/07 5
本スライドでの注意点
● 今後、グラフの頂点数をN、辺の数をMと記述する。
● 本スライドを見ただけでは、コードを書けるようには
なりません。頑張ってください。
– 困ったら -tsukasa_diar...
HCPC勉強会 2016/01/07 6
本スライドの主な内容
● 強連結成分分解
– 任意の有向グラフをDAGに変換するお話
● 最小共通先祖
– 根を持つ木における重要なクエリのお話
● H/L分解
– 根を持つ木に対する良い性質を持った分...
HCPC勉強会 2016/01/07 7
強連結成分分解
● 有向グラフの強連結な部分を潰してDAGにする
v1
v2
v5
v3
v4
v7
v8
v9
v6
V10
v1
V2,3,4,5
V7,8,9
v6
V10
Directed
Gr...
HCPC勉強会 2016/01/07 8
何が嬉しいの?
● 2-SATを爆速で解く(蟻本を読め)
– 強連結成分を考えることで解ける問題はたくさん
● DAGDAGできる!
● DAGは強い
– 色々な問題がDPで解ける
● 最長路問題(一般...
HCPC勉強会 2016/01/07 9
強連結成分分解のアルゴリズム
part-1
● DFSを2回するだけ
– 1回目:帰りがけ順を記憶
v1
v2
v5
v3
v4
v7
v8
v9
v6
V10
例えばこんなDFSをしたとする(赤はその...
HCPC勉強会 2016/01/07 10
強連結成分分解のアルゴリズム
part-2
● DFSを2回するだけ
– 2回目:帰りが遅かった頂点から順に逆辺を使ったDFS
– 何が起こるのか?
● すでに訪れた頂点を避けると、強連結成分ごとにD...
HCPC勉強会 2016/01/07 11
1度にたどった頂点をまとめれば完成
● DFSするだけなので計算量はO(N+M)
● なぜうまくいく?
– 強連結な部分は辺を逆向きにしても強連結
● 正方向で全部辿れるなら逆方向でも辿れる
– DF...
HCPC勉強会 2016/01/07 12
さらっと事前知識:木について
根
両親
妹
(願望)
ワイ
子供
(願望)
葉
姉
● 根
– 一番上の頂点
– これを定めた木を根付き木と言う
● 先祖
– 根を定めたとき自分より上にいる頂点
– ...
HCPC勉強会 2016/01/07 13
最小共通先祖(LCA)
● 根付き木のある2頂点について、共通する先祖のう
ち最も根から遠いもの
– クエリとして良く問われる
根
両親
妹
(願望)
ワイ
子供
(願望)
葉
姉
姪
(願望)
2つ...
HCPC勉強会 2016/01/07 14
二分法を用いて求める
● 着眼点
– uとvの高さが同じなら、それぞれから「ある値だけ登っ
た位置」以降にu,vの全ての共通先祖がある
– 「ある値だけ登った位置」がLCA
● uとvが初めてぶつかる...
HCPC勉強会 2016/01/07 15
前処理
● DFSで各頂点の深さと1つ上の先祖を記憶
● 各頂点の2k
個上の先祖を求める
– kは2k
>maxdepth
となる最小のkまで考えれば良い
● だいたいは雑に k = log(N)と...
HCPC勉強会 2016/01/07 16
クエリ処理
● 2頂点u,vのLCAを二分法により求める
● 一気に登るアルゴリズム
– uとvの高さが合うように深い方を登らせる
● これを二分法によりO(log(N))で行う
– uとvが初めてぶ...
HCPC勉強会 2016/01/07 17
クエリ処理 part-1
● uが深いとして、vとの高さが合うまでuを登らせる
– vの高さを超えない範囲で一気に登る
● 2k
登ってもvの高さを超えないなら u = parent[u][k]
● ...
HCPC勉強会 2016/01/07 18
クエリ処理 part-2
● 2k
個上の先祖情報を用いて一気に登る
– 2k
個上の先祖が違うならu,v共に2k
個登る
● If (parent[u][k] != parent[v][k]) th...
HCPC勉強会 2016/01/07 19
RMQ(Range Minimum Query)を用いて求める
● DFSの訪問順序を記憶
– v1
→v2
→v4
→v7
→v4
→v2
→v5
→v2
→v1
→v3
→v6
→v3
→v1
●...
HCPC勉強会 2016/01/07 20
事前知識:パス
● 一直線に書くことができるグラフ
– 閉路がない
– 木の特殊系とも見れる
HCPC勉強会 2016/01/07 21
H/L分解
● Heavy−Light Decompositionのこと
● 根付き木をいくつかのパスに分解する
v1
v2
v4
v5
v3
v6
v7
v8
v9
v11
v10
v1
v2
v5...
HCPC勉強会 2016/01/07 22
H/L分解の規則
● 規則
– 枝をHeavy-EdgeとLight-Edgeに分ける
● 子孫の半分以上を持つ枝をHeavyで他はLightとするだけ
– Heavy-Edgeをつないでパスにする
...
HCPC勉強会 2016/01/07 23
H/L分解のうまみ
● 新しい木は高さがO(log(N))
– 潰した木に残っている辺はLight-Edgeのみ
– Light-Edgeで結ばれた先は |子孫| <= N/2
– Light-Edg...
HCPC勉強会 2016/01/07 24
H/L分解のうまい利用法(雑)
● O(log(N))でLCAを求められる
● データ構造との組合せ
– BIT
– SegmentTree
● コイツデナグルトキノモンダイダイタイトケルツヨイ
– ...
HCPC勉強会 2016/01/07 25
HL分解〜SegmentTreeを添えて〜
● 実際の問題で使い方を雑に説明します
● AOJ 2667 Tree を参照してください
– http://judge.u-aizu.ac.jp/onli...
HCPC勉強会 2016/01/07 26
HL分解〜SegmentTreeを添えて〜
● とりあえずH/L分解してSeg木を付ける
v1
v2
v5
v8
v10
v4
v6
v3
v7
v9
v11
根
cost 3 2 5 1
1 3
3...
HCPC勉強会 2016/01/07 27
HL分解〜SegmentTreeを添えて〜
v1
v2
v5
v8
v10
v4
v6
v3
v7
v9
v11
根
cost 3 2 5 1
1 3
3 2 5 1
1
3
5 2
5
2
v5
か...
HCPC勉強会 2016/01/07 28
HL分解〜SegmentTreeを添えて〜
v1
v2
v5
v8
v10
v4
v6
v3
v7
v9
v11
根
cost 3 2 5 1
1 3
3 2 5 1
1
3
5 2
5
2
v2
よ...
HCPC勉強会 2016/01/07 29
本スライドはここまで
蟻本とかWeb検索の方が圧倒的情報量
Nächste SlideShare
Wird geladen in …5
×

目指せグラフマスター

1.486 Aufrufe

Veröffentlicht am

グラフマスターに、俺はなる!

20160107

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

目指せグラフマスター

  1. 1. HCPC勉強会 2016/01/07 1 HCPC勉強会 2016/01/07 グラフマスターに、俺はなる! M2 鈴木 浩史
  2. 2. HCPC勉強会 2016/01/07 2 さらっと事前知識:グラフとはなんぞや ● グラフ – 頂点(○ぽいやつ)を辺(線分)で結んだ図形 ● example – ○が人 → 友人関係の図 – ○が状態 → 状態遷移図 – 頂点や辺には値が付けられることがある – 辺は向きを持つことがある(有向グラフ) 戦闘力1 戦闘力 53万 戦闘力 10万 戦闘力5 友情0 友情0 友情0 友情100 友情50 就寝 起床 寝坊 研究室 二度寝 帰宅
  3. 3. HCPC勉強会 2016/01/07 3 さらっと事前知識:グラフの重要な用語 ● 閉路 – ある頂点から開始して同じ辺を2度通らずに戻る路 ● 連結 – 辺に向きがないとして全ての頂点が互いに行き来できる ● 木 – 閉路のない連結なグラフ ● 今回は特に辺に向きがないことにする – 頂点に葉、子孫、先祖、根など特別な呼び方がある ● 強連結 – 辺に向きがあるとき、全ての頂点が互いに行き来できる
  4. 4. HCPC勉強会 2016/01/07 4 さらっと事前知識:DAG ● 非巡回有向グラフ(Directed Acyclic Graph : DAG) – 辺に向きがあり閉路のないグラフ ● トポロジカル順序 – 各頂点が自身より若い頂点に辿りつけないような順序 ● 求め方 – 向けられている辺の数が0の頂点を消して番号付けることを繰り返す – DFSの帰りがけ順が遅いものから番号付けをする – 一意的ではない(大体の場合で気にしないけど) 2 6 1 4 3 5 7
  5. 5. HCPC勉強会 2016/01/07 5 本スライドでの注意点 ● 今後、グラフの頂点数をN、辺の数をMと記述する。 ● 本スライドを見ただけでは、コードを書けるようには なりません。頑張ってください。 – 困ったら -tsukasa_diary github [検索]- – いや、蟻本読めよ ● 蟻本読め
  6. 6. HCPC勉強会 2016/01/07 6 本スライドの主な内容 ● 強連結成分分解 – 任意の有向グラフをDAGに変換するお話 ● 最小共通先祖 – 根を持つ木における重要なクエリのお話 ● H/L分解 – 根を持つ木に対する良い性質を持った分解のお話 – ぶっちゃけ、競プロには必要ない ● 知ってると無理やり問題を殴れるだけ ● 趣味でしかない
  7. 7. HCPC勉強会 2016/01/07 7 強連結成分分解 ● 有向グラフの強連結な部分を潰してDAGにする v1 v2 v5 v3 v4 v7 v8 v9 v6 V10 v1 V2,3,4,5 V7,8,9 v6 V10 Directed Graph DAG! DAG!! 強連結な部分 強連結成分
  8. 8. HCPC勉強会 2016/01/07 8 何が嬉しいの? ● 2-SATを爆速で解く(蟻本を読め) – 強連結成分を考えることで解ける問題はたくさん ● DAGDAGできる! ● DAGは強い – 色々な問題がDPで解ける ● 最長路問題(一般には難しい)は有名 ● 強連結成分ごとに前処理して、 DAGに潰してDPするのは典型 – DPはDAGをトポロジカル順にたどるアルゴリズムと考 えることができる dp[from] dp[to1] dp[to2]
  9. 9. HCPC勉強会 2016/01/07 9 強連結成分分解のアルゴリズム part-1 ● DFSを2回するだけ – 1回目:帰りがけ順を記憶 v1 v2 v5 v3 v4 v7 v8 v9 v6 V10 例えばこんなDFSをしたとする(赤はその頂点から帰るタイミング) v1 →v2 →v3 →v6 →v9 →v10 →v9 →v7 →v8 →v7 →v9 →v6 →v3 →v4 →v5 →v4 →v3 →v2 →v1 12 3 4 5 6 7 8 9 10
  10. 10. HCPC勉強会 2016/01/07 10 強連結成分分解のアルゴリズム part-2 ● DFSを2回するだけ – 2回目:帰りが遅かった頂点から順に逆辺を使ったDFS – 何が起こるのか? ● すでに訪れた頂点を避けると、強連結成分ごとにDFSが停止 v1 v2 v5 v3 v4 v7 v8 v9 v6 V10 12 3 4 5 6 7 8 9 10 1回目 2回目 3回目 4回目 5回目 辺の向きが逆のグラフ
  11. 11. HCPC勉強会 2016/01/07 11 1度にたどった頂点をまとめれば完成 ● DFSするだけなので計算量はO(N+M) ● なぜうまくいく? – 強連結な部分は辺を逆向きにしても強連結 ● 正方向で全部辿れるなら逆方向でも辿れる – DFSの帰りがけ順が遅い = 完成したDAGでトポ順が早い ● 完成DAGでのDFS帰りがけ順を考えれば当然 – 逆辺のDFSならトポ順で後の強連結成分を訪れない – つまり、トポ順に強連結成分を舐めることになる v1 v2 v5 v3 v4 v7 v8 v9 v6 V10 12 3 4 5 6 7 8 9 10 v1 V2,3,4,5 V7,8,9 v6 V10
  12. 12. HCPC勉強会 2016/01/07 12 さらっと事前知識:木について 根 両親 妹 (願望) ワイ 子供 (願望) 葉 姉 ● 根 – 一番上の頂点 – これを定めた木を根付き木と言う ● 先祖 – 根を定めたとき自分より上にいる頂点 – 自分自身も含むことに注意 ● 子孫 – 根を定めたとき自分より下にいる頂点 ● 葉 – 辺が1本しか出ていない頂点 – 根を定めたとき子孫を持たない頂点 姪 (願望)
  13. 13. HCPC勉強会 2016/01/07 13 最小共通先祖(LCA) ● 根付き木のある2頂点について、共通する先祖のう ち最も根から遠いもの – クエリとして良く問われる 根 両親 妹 (願望) ワイ 子供 (願望) 葉 姉 姪 (願望) 2つの頂点 最小共通先祖
  14. 14. HCPC勉強会 2016/01/07 14 二分法を用いて求める ● 着眼点 – uとvの高さが同じなら、それぞれから「ある値だけ登っ た位置」以降にu,vの全ての共通先祖がある – 「ある値だけ登った位置」がLCA ● uとvが初めてぶつかる位置がLCAということ ● やること – 前処理:各頂点について深さと2k 個上の先祖を記憶 – クエリ処理:二分法で一気に登る
  15. 15. HCPC勉強会 2016/01/07 15 前処理 ● DFSで各頂点の深さと1つ上の先祖を記憶 ● 各頂点の2k 個上の先祖を求める – kは2k >maxdepth となる最小のkまで考えれば良い ● だいたいは雑に k = log(N)とする – 2k 個上の先祖 = 2k-1 個上の先祖の2k-1 個上の先祖 v1 v2 v4 v5 v3 v6 v7 v8 k = 0 はDFSによってわかっている kを1から初めて以下のDPをすれば良い! v9 v10 k=1 k=2 前処理の計算量 DFS-part : O(N) DP-part : O(N log(N)) 全体 : O(N log(N)) parent[v][k] = parent[parent[v][k-1]][k-1]
  16. 16. HCPC勉強会 2016/01/07 16 クエリ処理 ● 2頂点u,vのLCAを二分法により求める ● 一気に登るアルゴリズム – uとvの高さが合うように深い方を登らせる ● これを二分法によりO(log(N))で行う – uとvが初めてぶつかる直前まで一気に登る ● これも二分法によりO(log(N))で行う – 全体でO(log(N))で処理
  17. 17. HCPC勉強会 2016/01/07 17 クエリ処理 part-1 ● uが深いとして、vとの高さが合うまでuを登らせる – vの高さを超えない範囲で一気に登る ● 2k 登ってもvの高さを超えないなら u = parent[u][k] ● 次に登る値の最大値が半分(2k →2k-1 )になっていく v u u v vを超えない ギリギリ vを超える O(log(N))
  18. 18. HCPC勉強会 2016/01/07 18 クエリ処理 part-2 ● 2k 個上の先祖情報を用いて一気に登る – 2k 個上の先祖が違うならu,v共に2k 個登る ● If (parent[u][k] != parent[v][k]) then 登る; ● これもまた登る値の最大値が半分(2k →2k-1 )になっていく u v u v ぶつからない ギリギリ ここがLCA O(log(N))
  19. 19. HCPC勉強会 2016/01/07 19 RMQ(Range Minimum Query)を用いて求める ● DFSの訪問順序を記憶 – v1 →v2 →v4 →v7 →v4 →v2 →v5 →v2 →v1 →v3 →v6 →v3 →v1 ● 2頂点間の訪問経路上にLCAがある – v5 とv7 のLCAは? ● Answer. v2 – v1 →v2 →v4 →v7 →v4 →v2 →v5 →v2 →v1 →v3 →v6 →v3 →v1 ● 2頂点間の訪問経路上で最も深さの小さい頂点がLCA – 深さに関するRMQでLCAの位置がわかる – v1 →v2 →v4 →v7 →v4 →v2 →v5 →v2 →v1 →v3 →v6 →v3 →v1 – 0 →1 →2 →3 →2 →1 →2 →1 →0 →1 →2 →1 →0 v1 v2 v4 v3 v5 v6 v7 ※行きがけ順のインデクスで考える SegmentTreeを使う場合 前処理DFS+Seg木構築:O(N) クエリ処理:O(log(N)) u v LCA
  20. 20. HCPC勉強会 2016/01/07 20 事前知識:パス ● 一直線に書くことができるグラフ – 閉路がない – 木の特殊系とも見れる
  21. 21. HCPC勉強会 2016/01/07 21 H/L分解 ● Heavy−Light Decompositionのこと ● 根付き木をいくつかのパスに分解する v1 v2 v4 v5 v3 v6 v7 v8 v9 v11 v10 v1 v2 v5 v8 v10 v4 v6 v3 v7 v9 v11 1つのパスを1つのノードに潰すと、 より小さな木として考えることができる!
  22. 22. HCPC勉強会 2016/01/07 22 H/L分解の規則 ● 規則 – 枝をHeavy-EdgeとLight-Edgeに分ける ● 子孫の半分以上を持つ枝をHeavyで他はLightとするだけ – Heavy-Edgeをつないでパスにする v1 v2 v4 v5 v3 v6 v7 v8 v9 v11 v10 Heavy!! 性質がほぼ同じ分解として、 子孫の最も多い枝をHeavyと考える分解もある。 (僕はいつもこっちを使っている)
  23. 23. HCPC勉強会 2016/01/07 23 H/L分解のうまみ ● 新しい木は高さがO(log(N)) – 潰した木に残っている辺はLight-Edgeのみ – Light-Edgeで結ばれた先は |子孫| <= N/2 – Light-Edgeをたどった先では頂点数が半分になる ● 新しい木の頂点はパスを保持する – パスに対する高速なアルゴリズムと組合せられる – 1次元配列を用いたデータ構造で色々管理できる
  24. 24. HCPC勉強会 2016/01/07 24 H/L分解のうまい利用法(雑) ● O(log(N))でLCAを求められる ● データ構造との組合せ – BIT – SegmentTree ● コイツデナグルトキノモンダイダイタイトケルツヨイ – 他にも色々あるんだろうなぁ。。。 ● 結局のところ – 根付き木に関する多くのクエリをO(log(N))とか O(log2 (N))とかで解決
  25. 25. HCPC勉強会 2016/01/07 25 HL分解〜SegmentTreeを添えて〜 ● 実際の問題で使い方を雑に説明します ● AOJ 2667 Tree を参照してください – http://judge.u-aizu.ac.jp/onlinejudge/description.jsp? id=2667
  26. 26. HCPC勉強会 2016/01/07 26 HL分解〜SegmentTreeを添えて〜 ● とりあえずH/L分解してSeg木を付ける v1 v2 v5 v8 v10 v4 v6 v3 v7 v9 v11 根 cost 3 2 5 1 1 3 3 2 5 1 1 3 5 2 5 2 13 3 1 Seg0 Seg1 Seg2 Seg3 Seg4 All 3 2 3 3 2 木をDFSするとき、親子関係の 区間表現も作っておくことで、 各Seg木に対する 全範囲への追加コストを、 別のSeg木で管理する Seg1Seg0 Seg2 Seg3 Seg4 図はいくつかクエリ処理した後だと 思ってくださいオナシャス
  27. 27. HCPC勉強会 2016/01/07 27 HL分解〜SegmentTreeを添えて〜 v1 v2 v5 v8 v10 v4 v6 v3 v7 v9 v11 根 cost 3 2 5 1 1 3 3 2 5 1 1 3 5 2 5 2 v5 からv7 へのcostは? 13 3 1 ここ足す ここ 高さがlog(N)なので O(log2 (N)) All 3 2 3 3 2 木をDFSするとき、親子関係の 区間表現も作っておくことで、 各Seg木に対する 全範囲への追加コストを、 別のSeg木で管理する Seg0 Seg1 Seg2 Seg3 Seg4 ここ足す Seg1Seg0 Seg2 Seg3 Seg4
  28. 28. HCPC勉強会 2016/01/07 28 HL分解〜SegmentTreeを添えて〜 v1 v2 v5 v8 v10 v4 v6 v3 v7 v9 v11 根 cost 3 2 5 1 1 3 3 2 5 1 1 3 5 2 5 2 v2 より下の辺のcostを +x 13 3 1 +x ※範囲更新可能な SegmentTreeでやるべき All 3 2 3 3 2 木をDFSするとき、親子関係の 区間表現も作っておくことで、 各Seg木に対する 全範囲への追加コストを、 別のSeg木で管理する O(log(N))で更新できた!Seg0 Seg1 Seg2 Seg3 Seg4 v2 は[seg1, seg3]の先祖 +x Seg1Seg0 Seg2 Seg3 Seg4
  29. 29. HCPC勉強会 2016/01/07 29 本スライドはここまで 蟻本とかWeb検索の方が圧倒的情報量

×