45
競技プログラミング練習会 2015 Normal 32015/05/01 長嶺英朗(ID:hnagamin)

競技プログラミング練習会2015 Normal 第3回

Embed Size (px)

Citation preview

Page 1: 競技プログラミング練習会2015 Normal 第3回

競技プログラミング練習会2015 Normal

第3回

2015/05/01長嶺英朗(ID:hnagamin)

Page 2: 競技プログラミング練習会2015 Normal 第3回

目次

● グラフ– グラフとは– グラフに関する用語

● 最短経路問題● ベルマンフォード法● ワーシャルフロイド法

Page 3: 競技プログラミング練習会2015 Normal 第3回

グラフ

この辺りのページの多くは、http://www.slideshare.net/KMC_JP/graph-and-treeから引用しています

Page 4: 競技プログラミング練習会2015 Normal 第3回

グラフ

●頂点と辺の集合

●辺は頂点と頂点を結ぶ

●辺に向きがあるものを有向グラフ、向きのないものを無向グラフという

頂点

辺無向グラフ

Page 5: 競技プログラミング練習会2015 Normal 第3回

グラフ

●頂点と辺の集合

●辺は頂点と頂点を結ぶ

●辺に向きがあるものを有向グラフ、向きのないものを無向グラフという

頂点

辺有向グラフ

Page 6: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●道(パス):一続きの頂点の列

Page 7: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●閉路(サイクル):始点と終点が同じパス

Page 8: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●距離:2頂点を結ぶ最短の道の長さ

距離: 2

Page 9: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●直径:距離の最大値

直径: 2

Page 10: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●ループ:辺の両端が同じ頂点になっているもの

Page 11: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●多重辺:辺の両端の組が等しい複数の辺

Page 12: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●単純グラフ:ループも多重辺も無いグラフ

単純グラフでない

Page 13: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●単純グラフ:ループも多重辺も無いグラフ

単純グラフである

Page 14: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●連結グラフ:どの2点間にも道があるグラフ

連結でない

Page 15: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●連結グラフ:どの2点間にも道があるグラフ

連結である

Page 16: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●次数:頂点に接続している辺の本数

3

4

5

4

5

3

Page 17: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●正則グラフ:全頂点の次数が等しいグラフ

4

4

4

4

4

4

Page 18: 競技プログラミング練習会2015 Normal 第3回

グラフに関する用語

●完全グラフ:どの2点間にも辺があるグラフ

Page 19: 競技プログラミング練習会2015 Normal 第3回

グラフの実装

●隣接行列

●グラフを2次元配列で表す

●iからjにコストwの辺があるときa[i][j]=wとする

●実装が楽

●頂点数が多くなるとメモリを浪費する

●多重辺への対応が難しい

0 1 2 3

0 0 10 15 0

1 20 0 60 0

2 0 0 0 30

3 0 0 0 0

1

0

2 310 20

60

15

30

Page 20: 競技プログラミング練習会2015 Normal 第3回

グラフの実装

●隣接行列

●グラフを2次元配列で表す

●iからjにコストwの辺があるときa[i][j]=wとする

●実装が楽

●頂点数が多くなるとメモリを浪費する

●多重辺への対応が難しい

0 1 2 3

0 -1 10 15 -1

1 20 -1 60 -1

2 -1 -1 -1 30

3 -1 -1 -1 -1

1

0

2 310 20

60

15

30

Page 21: 競技プログラミング練習会2015 Normal 第3回

グラフの実装

●隣接行列

●グラフを2次元配列で表す

●iからjにコストwの辺があるときa[i][j]=wとする

●実装が楽

●頂点数が多くなるとメモリを浪費する

●多重辺への対応が難しい

0 1 2 3

0 ∞ 10 15 ∞

1 20 ∞ 60 ∞

2 ∞ ∞ ∞ 30

3 ∞ ∞ ∞ ∞

1

0

2 310 20

60

15

30

Page 22: 競技プログラミング練習会2015 Normal 第3回

グラフの実装

●隣接グラフ●各頂点から伸びる辺のリスト

●無向グラフのときは互いに逆向きの辺が2本あると考える

●頂点数が多くても大丈夫

●多重辺があっても大丈夫

0 (1,10),(2,15)

1 (0,20),(2,60)

2 (3,30)

3 -

1

0

2 310 20

60

15

30

Page 23: 競技プログラミング練習会2015 Normal 第3回

最短経路問題

Page 24: 競技プログラミング練習会2015 Normal 第3回

最短経路問題

●頂点間の距離を求める問題●全点対最短経路問題…全ての頂点間の距離

●単一始点最短経路問題…ある点から各点への距離

1

0

23

1020

60

15

30頂点1 0: 20⇒頂点1 1: 0⇒頂点1 2: 35⇒頂点1 3: 65⇒

単一始点最短経路問題の例

Page 25: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法

●単一始点最短経路問題を解く

●計算量O(VE)

●V: 頂点数, E: 辺の数

Page 26: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法のアイデア

●各頂点への暫定的な最短経路を保存しておく

●各辺を使うことで最短経路を更新できるか調べる

●コストwの辺i→jについて、dj > di + w か調べる

●diは始点からiへの距離

Page 27: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●始点を除く各頂点に対してdi = ∞とする

●実際には(とても大きい)有限の数にする

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di ∞ 0 ∞ ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

Page 28: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di ∞ 0 ∞ ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

Page 29: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di ∞ 0 ∞ ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d1 = 0 < d

0 + 10 = ∞+10

(更新しない)

Page 30: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di ∞ 0 ∞ ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d2 = ∞ < d

0 + 10 = ∞+15

(更新しない)

Page 31: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 ∞ ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d0 = ∞ > d

1 + 20 = 20

(更新する)

Page 32: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 60 ∞

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d2 = ∞ > d

1 + 60 = 60

(更新する)

Page 33: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 60 90

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d3 = ∞ > d

2 + 30 = 90

(更新する)

Page 34: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 60 90

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d1 = 0 < d

0 + 10 = 30

(更新しない)

Page 35: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 35 90

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d2 = 60 > d

0 + 15 = 35

(更新する)

Page 36: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 35 90

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d0 = 20 = d

1 + 20 = 20

(更新しない)

Page 37: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 35 90

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d2 = 35 < d

1 + 60 = 60

(更新しない)

Page 38: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●各辺に対してd終点 > d始点+コストでないか調べる

1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 35 65

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

d3 = 90 > d

2 + 30 = 65

(更新する)

Page 39: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の動作

●辺のリストを1周したとき、距離を1回も更新できなければもう距離を更新できないので終了する

●このときのdiが最短距離1

0

23

1020

60

15

30

頂点i 0 1 2 3

距離di 20 0 35 65

辺のリスト(0,1,10), (0,2,15), (1,0, 20), (1,2,60), (2,3,30)

Page 40: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の計算量

●負の閉路がないとき

●最初は始点から始点への距離(0)が確定している

●辺のリストを1周すると、距離が確定した頂点に隣接するもののうち少なくとも1つの距離が確定する

●この頂点の距離は今後2度と更新されない

●従って、(V-1)周すると全ての頂点の距離が定まる

●O((V-1)E) = O(VE)

Page 41: 競技プログラミング練習会2015 Normal 第3回

ベルマンフォード法の計算量

●負の閉路があるとき●一部の頂点について“最短距離”が定まらない

●辺のリストをV周しても、負の閉路を構成する頂点の最短距離は更新される

●V周目でも更新されると負の閉路があることが分かるので、そこで計算を打ち切る

●O(VE)で負の閉路の検出ができる

Page 42: 競技プログラミング練習会2015 Normal 第3回

ワーシャルフロイド法

●全点対最短経路問題を解く

●計算量O(V3)

●V: 頂点数

●実装が簡単

●頂点数が小さい場合には単一始点最短経路問題でもこれを使うことがある

Page 43: 競技プログラミング練習会2015 Normal 第3回

ワーシャルフロイド法のアイデア

●dij > dik + dkj なら、iからkを経由してjに行くことで

iからjへより小さいコストで行くことができる

●全ての(i, j, k)についてこれを調べる

k

ji dij

dik dkj

Page 44: 競技プログラミング練習会2015 Normal 第3回

ワーシャルフロイド法の実装

●隣接行列を持っておくと良い

for (int i = 0; i < V; i++) {for (int j = 0; j < V; j++) {

d[i][j] = (i == j ? 0 : INFINITY);}

}for (int i = 0; i < E; i++) {

d[edges[i].from][edges[i].to] = edges[i].cost;}

for (int k = 0; i < V; i++) {for (int i = 0; j < V; j++) {

for (int j = 0; k < V; k++) {d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

}}

}

行列の初期化

最短距離の更新

Page 45: 競技プログラミング練習会2015 Normal 第3回

ワーシャルフロイド法の計算量

●プログラムの形式から明らかにO(V3)