Advanced Competitive Programming

Slides:



Advertisements
Similar presentations
第7章 樹與二元樹 (Trees and Binary Trees)
Advertisements

動畫與遊戲設計 Data structure and artificial intelligent
《高级人工智能》参考书目 马少平,朱小燕。人工智能。清华大学出版社。 蔡自兴,徐光祐。人工智能及其应用。清华大学出版社。
武进区三河口中学欢迎您.
Chapter 10 Graphs.
Network Optimization: Models & Algorithms
ACM/ICPC暑期集训讲座 二分图匹配 cnhawk
Chapter 12 圖形結構 12.1 圖形的一些專有名詞 12.2 圖形資料結構表示法 12.3 圖形追蹤 12.4 擴展樹
第13章 游戏中的人工智能.
資料結構與C++程式設計進階 資料結構概論 講師:林業峻 CSIE, NTU 6/ 7, 2010.
第7章 图论基础与应用 PART A 《可视化计算》.
Minimum Spanning Trees
Chap4 Tree.
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
Chap5 Graph.
7.5 擴張樹 (Spanning Tree) 一個無向相連圖 G 的子圖 G’ 如果可用最少的邊來連接G 的
Chap5 Graph.
Chapter8 Binary and Other Trees
講師:郭育倫 第3章 基本資料結構 講師:郭育倫
第8章 圖形結構(Graphs) 8-1 圖形的基本觀念 8-2 圖形的表示法 8-3 圖形的走訪 8-4 擴張樹
Chapter 6 Graph Chang Chi-Chung
第八章 图 图的基本概念 图的存储结构 图的遍历与连通性 最小生成树 最短路径 活动网络.
The Greedy Method.
演算法方式總覽 The Divide-and-Conquer Strategy (個各擊破)(binary Searching、Quick Sort…. ) The Greedy Method(貪婪演算法) (Prim MST、Kruskal MST、Djikstra's algorithm) Dynamic.
圖論 (Graph Theory) B 電機四 大鳥 B 電機四 酋長 B 電機四 炫大
Bellman 查經 兩個有關婚宴的比喻 馬太福音 22:1~14, 25:1~13.
Graph 2 Michael Tsai 2012/5/1 連載: 學生上課睡覺姿勢大全
Journal of High Speed Networks 15(2006)
LOM-領隊導向多人連線遊戲自動匹配演算法
101北一女中 資訊選手培訓營 最短路徑 Shortest Path Nan.
Chapter 7 圖形與網路 資料結構導論 - C語言實作.
Chapter12 Graphs Definitions Applications Properties
Yuzhong Qu Nanjing University
Ch07 圖形與網路 淡江大學 周清江
Advisor : Prof. Frank Y.S. Lin Presented by Yen-Yi, Hsu
第9章 基本图算法 本章内容将包含基本的图形表示法,以及先深搜寻,先广搜寻,拓朴排序,Strongly Connected Components。
第六节 最小生成树.
数据结构概论 第7章 图 董黎刚 浙江工商大学信电学院 2019年4月8日.
第7章 樹與二元樹(Trees and Binary Trees)
圖論的介紹 第二組 徐榮德 鄭又齊 陳俊嘉.
最大網路流 Max (Network) Flow
生成树.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
Disjoint Sets Michael Tsai 2013/05/14.
第8章 图 8.1 图的基本概念和基本操作 8.2 图的邻接矩阵存储结构 8.3 图的邻接表存储结构 8.4 图的其他存储结构
Course 8 回溯、分枝與限制 Backtracking, Branch-and-Bound
資料結構簡介 綠園.
鄧姚文 資料結構 第八章:圖(Graph) 鄧姚文
最短通路问题.
進階資料結構(2) Disjoint Sets
赵才荣 同济大学,电子与信息工程学院,智信馆410室
电工技术 制作:上海君达 2007年9月
Bellman 查經 處理憂慮 馬太福音 6:25~34.
生成树 离散数学─树 南京大学计算机科学与技术系.
Advanced Competitive Programming
Advanced Competitive Programming
Advanced Competitive Programming
圖形結構 Graph Structure chapter 9 德明科技大學資訊科技系.
Tree Riddles Kun-Mao Chao (趙坤茂)
Tree Riddles Kun-Mao Chao (趙坤茂)
最大網路流 Max (Network) Flow
Maximum Flow.
Advanced Competitive Programming
11506: Angry Programmer ★★★★☆ 題組:Contest Set Archive with Online Judge
Graph 1 Michael Tsai 2012/4/24 連載: 學生上課睡覺姿勢大全
JAVA 程式設計與資料結構 第十七章 Tree.
Advanced Competitive Programming
10801: Lift Hopping ★★★☆☆ 題組:Problem Set Archive with Online Judge
JAVA 程式設計與資料結構 第二十一章 Graph.
Presentation transcript:

Advanced Competitive Programming 國立成功大學ACM-ICPC程式競賽培訓隊 nckuacm@imslab.org Department of Computer Science and Information Engineering National Cheng Kung University Tainan, Taiwan

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

Graph 圖 (Graph),是一個由邊 (Edge) 集合與點 (Vertex) 集合所組成的資料結構。

Graph 圖 (Graph),是一個由邊 (Edge) 集合與點 (Vertex) 集合所組成的資料結構。 G = (E, V) 為圖

Graph 點 (vertex): 組成圖的最基本元素

Graph u v 點 (vertex): 組成圖的最基本元素 邊 (edge): 點與點的關係 通常用 u 表示邊的起端,v 表示邊的終端

Graph 點 (vertex): 組成圖的最基本元素 邊 (edge): 點與點的關係 通常用 u 表示邊的起端,v 表示邊的終端 有向圖 (directed graph): 邊帶有方向性 u -> v,表示 u 能走到 v,但 v 不保證走到 u

Graph 點 (vertex): 組成圖的最基本元素 邊 (edge): 點與點的關係 通常用 u 表示邊的起端,v 表示邊的終端 有向圖 (directed graph): 邊帶有方向性 u -> v,表示 u 能走到 v,但 v 不保證走到 u 無向圖 (undirected graph): 每條邊都是雙向的 u <-> v,表示 v 能到 u,u 能到 v

Graph 道路 (walk): 點邊相間的序列

Graph 道路 (walk): 點邊相間的序列 e.g.  v0e1v1e2v2...envn

Graph 道路 (walk): 點邊相間的序列 e.g.  v0e1v1e2v2...envn 路徑 (path): 點不重複的道路

Graph 道路 (walk): 點邊相間的序列 e.g. v0e1v1e2v2...envn 路徑 (path): 點不重複的道路 環 (cycle): 把路徑的起點與終點連接起來

Graph 道路 (walk): 點邊相間的序列, e.g. v0e1v1e2v2...envn 路徑 (path): 點不重複的道路 環 (cycle): 把路徑的起點與終點連接起來 走訪/遍歷 (traversal/search): 走完全部的點或邊

該怎麼表示一張圖呢

Graph 鄰接矩陣 用二維陣列表達點與點有無邊關係 E[u][v] = 1 表示 u 與 v 間有邊

Graph 鄰接矩陣 用二維陣列表達點與點有無邊關係 用特殊的值來表示無法到達的情況 E[u][v] = 1 表示 u 與 v 間有邊 例如 INT_MAX 或是 -1 或是 INF

Graph 鄰接表 vector<int> E[maxv]; to = E[from][0]; from to

Graph 鄰接表 E[2][0] = 3; 2 3

Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; 2 9 8 3

Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; E[2][1] = 9; 2 9 8 3

2 9 8 3 7 Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; E[2][1] = 9;

2 9 5 8 3 1 7 Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; E[2][1] = 9;

2 9 5 8 3 1 7 Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; E[2][1] = 9;

2 9 5 8 3 1 7 Graph 鄰接表 E[2][0] = 3; E[8][0] = 9; E[2][1] = 9;

Tree Tree 是一個有向無環連通圖

Tree Tree 是一個有向無環連通圖 節點 (node): 一般樹上的點

Tree Tree 是一個有向無環連通圖 節點 (node): 一般樹上的點 父 (parent): 節點能反向拜訪的第一個節點 子 (child): 節點能正向拜訪的第一個節點

Tree Tree 是一個有向無環連通圖 節點 (node): 一般樹上的點 父 (parent): 節點能反向拜訪的第一個節點 子 (child): 節點能正向拜訪的第一個節點 根 (root): 沒有父節點的節點 葉 (leaf): 沒有子節點的節點

Tree 每個點都是節點 根 G的父 B的子 葉 葉 葉 葉 葉 葉

Tree 祖先 (ancestor): 節點能反向拜訪的所有節點 孫子 (descendant): 節點能正向拜訪的所有節點

Tree 祖先 (ancestor): 節點能反向拜訪的所有節點 孫子 (descendant): 節點能正向拜訪的所有節點 深度 (depth): 從根到該節點所經過的邊數

Tree 祖先 (ancestor): 節點能反向拜訪的所有節點 孫子 (descendant): 節點能正向拜訪的所有節點 深度 (depth): 從根到該節點所經過的邊數 森林 (forest): 一個集合包含所有不相交的 Tree 每個非根節點只有一個父節點

Tree

Tree

Tree G的Depth為2

Tree G的祖先

Tree G的孫子

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

Minimum spanning tree

生成樹 給定連通圖 G = (E, V) 使用 E 子集連接所有的點 (屬於 V) 所得到的樹

生成樹 1 8 3 9 6 1 5 8 3 7 2 4

9 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

16 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

20 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

21 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

24 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

29 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

30 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

38 生成樹 1 8 3 9 6 1 5 8 3 7 2 4

38 生成樹 1 3 9 1 5 8 7 4

最小生成樹 給定連通圖 G = (E, V) 在所有生成樹中,找到邊權重總和最小的生成樹

29 最小生成樹 8 1 3 6 5 9 1 8 7 2 4

29 最小生成樹 8 1 3 6 5 1 2

兩個重要前提 樹是無環的連通圖 若圖只有點無任何邊,那每點都是彼此獨立連通塊

46 無環連通圖 8 3 9 6 1 8 7 4

兩個重要前提 樹是無環的連通圖 若圖只有點無任何邊,那每點都是彼此獨立連通塊

獨立的連通塊們

最小生成樹 Kruskal 演算法 Prim 演算法

最小生成樹 Kruskal 演算法 Prim 演算法

Kruskal 演算法 在產生生成樹以前,所有點都為獨立的連通塊 若兩個獨立的連通塊相連,整個圖就少一連通塊

1 1

如何產生生成樹 在連通塊 A 與連通塊 B 相連時確保不會產生環 最終就能得到一棵生成樹

1 1

5 1 4

12 1 7 4

20 1 8 7 4

23 3 1 8 7 4

31 8 3 1 8 7 4

40 8 3 9 1 8 7 4

46 8 3 9 6 1 8 7 4

怎樣不產生環 在連通塊 A 與連通塊 B 相連時確保不會產生環 A ≠ B ⟺ 加入新的邊不產生環

23 A 連通塊 1 8 3 6 5

23 B 連通塊 1 8 3 6 5

23 相連 1 8 3 9 6 5

32 相連 1 8 3 9 6 5

(☉д⊙) 產生環 3 5

怎樣不產生環 在連通塊 A 與連通塊 B 相連時確保不會產生環 A ≠ B ⟺ 加入新的邊不產生環

怎樣不產生環 在連通塊 A 與連通塊 B 相連時確保不會產生環 A ≠ B ⟺ 加入新的邊不產生環 所以過程中要確保挑的連通塊互為獨立

Kruskal 演算法 直覺的,每次相連選一個合法且權重最小的邊 最終得到的生成樹,就是最小生成樹

Kruskal 1 8 3 9 6 1 5 8 3 7 2 4

權重排序 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

1 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

1 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

1 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

2 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

2 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

2 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

4 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

4 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

4 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

7 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

7 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

7 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

10 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

10 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

10 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

(☉д⊙) 環 1 1 2 3 4 5 6 7 8 9 8 3 9 6 5 8 7

10 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

10 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

10 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

15 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

15 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

15 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

(☉д⊙) 環 1 1 2 3 4 5 6 7 8 9 8 3 9 6 5 8 3 4

21 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

(☉д⊙) 環 1 1 2 3 4 5 6 7 8 9 8 3 9 1 3 7 2 4

21 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

21 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

29 相連 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

29 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

29 檢查 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

(☉д⊙) 環 1 2 3 4 5 6 7 8 9 3 1 5 8 3 7 2 4

29 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

29 遍歷完成 1 1 2 3 4 5 6 7 8 9 8 3 9 6 1 5 8 3 7 2 4

29 最小生成樹 1 8 3 6 1 5 3 2

Kruskal 實作 若使用 DFS 判斷兩點是否屬於同個連通塊 則最終複雜度為 O(|E|2) 枚舉每個邊 O(|E|)

Kruskal 實作 是否為同個連通塊,是一個分類問題 兩連通塊獨立 ⟺ 彼此間沒有重複的點

Kruskal 實作 是否為同個連通塊,是一個分類問題 兩連通塊獨立 ⟺ 彼此間沒有重複的點

Kruskal 實作 是否為同個連通塊,是一個分類問題 兩連通塊獨立 ⟺ 彼此間沒有重複的點 也就是說,連通塊們是個 Disjoint Sets 可以用 Union-Find Forest 改善複雜度 第四週教材中有 Union-Find Forest 的介紹

Kruskal 實作 bool cmp(const edge &A, const edge &B) { return A.w < B.w; }

Kruskal 實作 vector<edge> E; // 邊集合 : . sort(E.begin(), E.end(), cmp); for (edge e: E) { int a = Find(e.u), b = Find(e.v); if (a != b) { Union(e.u, e.v); cost += E.w; MST.emplace_back(u, v, w); } }

Kruskal 實作 用 Union-Find Forest 改善複雜度 複雜度為 O(|E|log2|E| + |E|⋅ α)

Questions?

練習 UVa OJ 10369 Arctic Network AIZU 1280 Slim Span

最小生成樹 Kruskal 演算法 Prim 演算法

Prim 演算法 很類似的

兩個重要前提 樹是無環的連通圖 若圖只有點無任何邊,那每點都是彼此獨立連通塊

Prim 演算法 Prim 維護一個未完成的生成樹

Prim 演算法 Prim 維護一個未完成的生成樹 每次將樹周遭有最小權重的邊接到樹上, 使樹最終成長至最小生成樹

1 8 3 9 6 1 5 8 3 7 2 4

Prim 演算法 先隨便的挑任意點

1 8 3 9 6 1 5 8 3 7 2 4

Prim 演算法 先隨便的挑任意點 使它為初始的未完成的生成樹

Prim 演算法 先隨便的挑任意點 使它為初始的未完成的生成樹,稱它為 MST 明顯的,它是個無環連通圖

1 8 3 9 6 1 5 8 3 7 2 4

MST

Prim 演算法 直覺的,每次將 MST 周遭權重最小的邊接上去 那麼最終產生的生成樹為最小生成樹

1 8 3 9 6 1 5 8 3 7 2 4

6 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

6 MST 6

6 1 8 3 9 6 1 5 8 3 7 2 4

7 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

7 MST 1 6

7 1 8 3 9 6 1 5 8 3 7 2 4

10 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

10 MST 1 3 6

10 1 8 3 9 6 1 5 8 3 7 2 4

15 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

15 MST 1 3 6 5

15 1 8 3 9 6 1 5 8 3 7 2 4

23 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

23 MST 1 8 3 6 5

23 1 8 3 9 6 1 5 8 3 7 2 4

24 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

24 MST 1 8 3 6 1 5

24 1 8 3 9 6 1 5 8 3 7 2 4

26 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

26 MST 1 8 3 6 1 5 2

26 1 8 3 9 6 1 5 8 3 7 2 4

29 周圍最小邊 1 8 3 9 6 1 5 8 3 7 2 4

29 MST 1 8 3 6 1 5 3 2

Prim 實作 struct node { int id; // 點的編號 int w; // 連結到此點的權重 (邊權重) };

Prim 實作 vector<node> E[maxv]; // maxv 為最大節點數 : . /* 假設輸入完邊的資訊了 */

Prim 實作 /* 每次挑最小權重的邊 */ priority_queue<edge> Q; /* 初始的生成樹 (只有一個點) */ Q.push({1, 1, 0});

Prim 實作 while(!Q.empty()) { edge e = Q.top(); Q.pop(); int u = e.v; if(!vis[u]) { // 避免出現環 MST.push_back(e); cost += e.w; for(auto v: E[u]) if(!vis[v.id]) Q.push({u, v.id, v.w}); } vis[u] = true; }

Prim 實作 跟 Kruskal 比較 Prim 枚舉的是點 Kruskal 枚舉的是邊 其複雜度為 O(|E|log2|V|)

Questions?

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

Single-Source Shortest Paths

SSSP 給定 源點/起點(Source) 問每條路徑的最小成本 源點到各點的最小總成本

SSSP Breadth-First Search Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

SSSP Breadth-First Search Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

廣度優先搜尋

BFS 廣度優先搜尋 (Breadth-First Search) 簡稱 BFS a c p k o f g h i l z j

BFS 程式碼 queue<int> Q; Q.push(source); vis[source] = true; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (auto v: E[u]) { if (vis[v]) continue; vis[v] = true; Q.push(v); }

BFS 的點遍歷順序 a c p k o f g h i l z j

BFS 的點遍歷順序 1 2 3 4 5 6 7 8 9 A B C

第一個拜訪的為根 藍色為未曾拜訪 1 c p k o f g h i l z j

拜訪所有鄰點 黃色為拜訪中 1 2 p k o f g h i l z j

拜訪所有鄰點 1 2 3 k o f g h i l z j

拜訪所有鄰點 1 2 3 4 o f g h i l z j

拜訪所有鄰點 1 2 3 4 5 f g h i l z j

根拜訪完 紫色為拜訪完 1 2 3 4 5 f g h i l z j

拜訪所有鄰點 1 2 3 4 5 6 g h i l z j

拜訪所有鄰點 1 2 3 4 5 6 7 h i l z j

拜訪完 1 2 3 4 5 6 7 h i l z j

拜訪所有鄰點 1 2 3 4 5 6 7 8 9 A B j

拜訪完 1 2 3 4 5 6 7 8 9 A B j

拜訪完 1 2 3 4 5 6 7 8 9 A B j

拜訪完 1 2 3 4 5 6 7 8 9 A B j

拜訪完 1 2 3 4 5 6 7 8 9 A B j

拜訪完 1 2 3 4 5 6 7 8 9 A B j

拜訪所有鄰點 1 2 3 4 5 6 7 8 9 A B C

拜訪完 1 2 3 4 5 6 7 8 9 A B C

拜訪完 1 2 3 4 5 6 7 8 9 A B C

拜訪完 1 2 3 4 5 6 7 8 9 A B C

拜訪完 1 2 3 4 5 6 7 8 9 A B C

拜訪完 1 2 3 4 5 6 7 8 9 A B C

BFS 樹 1 2 3 4 5 6 7 8 9 A B C

BFS 樹 1 2 3 4 5 6 7 8 9 A B C

S 到 T S T

BFS 完 S T

BFS 完 S T

3 深度/成本: 3 S T

若邊權重 ≥ 1 1 8 3 4 6 1 5 8 3 7 S 2 T 4

若邊權重 ≥ 1 怎麼辦?

將權重切段 例如 x 權重,切成共 x 段的 1 權重邊

將權重切段 例如 3 權重 3

將權重切段 例如 3 權重,切成共 3 段的 1 權重邊 1 1 1

將權重切段 例如 3 權重,切成共 3 段的 1 權重邊 就能 BFS 了! 1 1 1

將權重切段 例如 3 權重,切成共 3 段的 1 權重邊 就能 BFS 了! 複雜度肯定會爆炸!

Questions?

單源最短路徑 Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

單源最短路徑 Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

Relaxation 想像自己是圖中的某點 v v

Relaxation u u 想像自己是圖中的某點 v 身旁有一些鄰點 u v u

Relaxation 14 5 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 9

Relaxation 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) 8 v 6 9

Relaxation 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 6 9

Relaxation 23 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 6 9

Relaxation 23 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 6 9

Relaxation 23 13 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 6 9

Relaxation 23 13 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 6 9

Relaxation 23 13 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 8 v 15 6 9

Relaxation 23 13 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 v 就能得知,源點到 v 的最小成本 8 v 15 6 9

Relaxation 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 v 就能得知,源點到 v 的最小成本 8 v 6 9

Relaxation 14 5 9 想像自己是圖中的某點 v 身旁有一些鄰點 u u 知道源點到他們那裡的最小成本 v 知道 u 到自己那裡的成本 (邊權重) v 能計算各點到 v 的成本 v 就能得知,源點到 v 的最小成本 8 13 6 9

Relaxation 實作 int update = cost[u] + w; // w := weight cost[v] = min(cost[v], update);

Questions?

單源最短路徑 Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

Dijkstra's algorithm

Dijkstra 實作 vector<node> E[maxn]; // 邊集合 : . /* 假設輸入完邊的資訊了 */

Dijkstra 實作 (初始化) memset(s, 0x3f, sizeof(s)); //初始為無限大 priority_queue<node> Q; Q.push({source, s[source] = 0});

Dijkstra 實作 while (!Q.empty()) { node u = Q.top(); Q.pop(); for (node v: E[u.id]) { int update = u.w + v.w; if (update < s[v.id]) Q.push({v.id, s[v.id] = update}); } }

1 8 3 4 6 1 5 8 3 7 s 2 4

∞ 初始化 1 8 ∞ 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪中 1 8 ∞ 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪鄰點 1 8 ∞ 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax! 1 8 5 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪鄰點 1 8 5 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax? 1 8 5 3 ∞ 4 ∞ 6 1 ∞ 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax! 1 8 5 3 ∞ 4 ∞ 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪完 1 8 5 3 ∞ 4 ∞ 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Queue 1 8 5 3 ∞ 4 ∞ 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪鄰點 1 8 5 3 ∞ 4 ∞ 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax? 1 8 5 3 ∞ 4 ∞ 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax! 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ 拜訪鄰點 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

∞ Relax? 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax! 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax? 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 No 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪完 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

關於 relaxation 5 這個拜訪完的節點 在未來有可能再被 relax 嗎?

6 拜訪完 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax? 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 No 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax? 1 8 5 3 ∞ 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax! 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪完 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 關於 relaxation 5 這些拜訪完的節點 在未來有可能再被 relax 嗎?

6 關於 relaxation 5 這些拜訪完的節點 在未來有可能再被 relax 嗎? 若答案為否定的, 這似乎叫做: 無後效性

6 拜訪完 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax? 1 8 5 3 14 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax! 1 8 5 3 12 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪完 1 8 5 3 12 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 12 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪完 1 8 5 3 12 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 拜訪鄰點 1 8 5 3 12 4 8 6 1 8 5 ∞ 8 3 7 2 ∞ ∞ 4

6 Relax! 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 19 4

6 拜訪完 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 19 4

6 無後效性 5 12 若 u 去 relax 了 v 8 8

6 無後效性 5 12 若 u 去 relax 了 v 則未來不管如何, v 不可能更新 u 8 8

6 無後效性 5 12 若 u 去 relax 了 v 則未來不管如何, v 不可能更新 u 因為 u 先來的 8 8

6 無後效性 5 12 若 u 去 relax 了 v 則未來不管如何, v 不可能更新 u 因為 u 先來的,在 u 之後挑的任何點 其值都比 u 大,並且邊權重恆正 ! 怎麼加都比 u 大 8 8

6 拜訪鄰點 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 19 4

6 Relax? 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 19 4

6 Relax! 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 15 4

6 拜訪完 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 15 4

6 拜訪鄰點 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 15 4

6 拜訪完 1 8 5 3 12 4 8 6 1 8 5 13 8 3 7 2 15 15 4

S 到 T? 1 8 3 4 6 1 5 8 3 7 S 2 T 4

15 1 8 3 12 4 6 1 8 5 13 8 3 7 2 15 4

Questions?

練習 POJ 3255 Roadblocks

單源最短路徑 Relaxation Dijkstra's algorithm Bellman-Ford's algorithm

Bellman-Ford's algorithm

Bellman-Ford 實作 vector<edge> E; : . /* 假設輸入完邊的資訊了 */

Bellman-Ford 實作 memset(s, 0x3f, sizeof(s)); // 初始無限大 s[source] = 0;

Bellman-Ford 實作 for (int i = 0; i < V.size(); i++) for (edge e: E) s[e.v] = min(s[e.v], s[e.u] + e.w);

1 8 3 4 2 5 8 s

∞ 初始化 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ No 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ No 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ No 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ No 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ No 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 ∞ 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax! 1 8 5 3 ∞ 4 ∞ 2 ∞ 5 8

∞ 1 8 5 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax? 1 8 5 3 ∞ 4 ∞ 2 ∞ 5 8

∞ Relax! 1 8 5 3 ∞ 4 ∞ 2 8 5 8

∞ 1 8 5 3 ∞ 4 ∞ 2 8 5 8

∞ Relax? 1 8 5 3 ∞ 4 ∞ 2 8 5 8

∞ No 1 8 5 3 ∞ 4 ∞ 2 8 5 8

∞ 1 8 5 3 ∞ 4 ∞ 2 8 5 8

∞ Relax? 1 8 5 3 ∞ 4 ∞ 2 8 5 8

6 Relax! 1 8 5 3 ∞ 4 ∞ 2 8 5 8

6 1 8 5 3 ∞ 4 ∞ 2 8 5 8

6 Relax? 1 8 5 3 ∞ 4 ∞ 2 8 5 8

6 Relax! 1 8 5 3 12 4 ∞ 2 8 5 8

6 1 8 5 3 12 4 ∞ 2 8 5 8

6 Relax? 1 8 5 3 12 4 ∞ 2 8 5 8

6 Relax! 1 8 5 3 12 4 ∞ 2 7 5 8

6 1 8 5 3 12 4 ∞ 2 7 5 8

6 Relax? 1 8 5 3 12 4 ∞ 2 7 5 8

6 Relax! 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 Relax? 1 8 5 3 12 4 8 2 7 5 8

6 No 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 Relax? 1 8 5 3 12 4 8 2 7 5 8

6 No 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 1 8 5 3 12 4 8 2 7 5 8

6 Relax! 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 1 8 5 3 11 4 8 2 7 5 8

6 結束了嗎? 1 8 5 3 11 4 8 2 7 5 8

結束了嗎? 結束了。

可是 要怎麼判斷,每個點都得到最短路了?

路就是一條直直的

所以 至多要做 |V| - 1 次的全部邊 relaxtion 剛剛的例子只做了 3 遍 自行證明吧

負權重邊 對每邊做至多 |V|−1 次 relaxation 後, 要是某邊還能 relaxation,

負權重邊 對每邊做至多 |V|−1 次 relaxation 後, 要是某邊還能 relaxation, 就表示有負權重邊能使路徑成本一直降低。

Questions?

練習 UVa OJ 558 Wormholes

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

A* search

評估函數 下一步到底該往哪走?

評估函數 下一步到底該往哪走? (透過轉移方程找可走鄰點)

評估函數 下一步到底該往哪走? 走下去,會更好嗎?

評估函數 下一步到底該往哪走? 走下去,會更好嗎? 好或不好,就是由評估函數決定 得自行設計

評估函數 g(n): 從起點到 n 點的成本 h(n): 從 n 點到終點的成本 f(n) = g(n) + h(n): 評估函數

例如 當求帶權重圖的單源最短路徑 g(n) = 從起點到 n 的最小成本 h(n) = 0 這個是, Dijkstra 演算法

例如 當求二維平面圖的單點到單點最短路徑 g(n) = 0 h(n) = n 點到終點的歐幾里得距離 這個是, Best-first search 演算法 不是 Breadth-first search

Outline 術語複習 Graph Tree 最小生成樹 A* 搜尋法則 單源最短路徑 全點對最短路徑

All-Pairs Shortest Paths

APSP 問任意點到任意點的最小成本

樸素解 利用剛才教的 SSSP 演算法們 對每個點都設定為源點 (source)

樸素解 利用剛才教的 SSSP 演算法們 對每個點都設定為源點 (source) 當然可以!

全點對最短路徑 Floyd-Warshall's Algorithm Johnson's Algorithm

全點對最短路徑 Floyd-Warshall's Algorithm Johnson's Algorithm

Floyd-Warshall's Algorithm

Floyd-Warshall 實作 int s[maxn][maxn]; for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) s[i][j] = G[i][j]; for (int k = 1; k <= N; k++) for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) s[i][j] = min(s[i][j], s[i][k] + s[k][j]);

狀態/轉移方程 設定狀態 𝑠 i,j,𝑘 為 𝑖 到 𝑗 只以 1,..,𝑘 為中間點的最小成本

狀態/轉移方程 設定狀態 𝑠 i,j,𝑘 為 𝑖 到 𝑗 只以 1,..,𝑘 為中間點的最小成本 𝑠 i,j,𝑘 = 𝑠 𝑖, 𝑗, 𝑘−1 若無經過 𝑘 s i,𝑘, 𝑘−1 +𝑠 𝑘, 𝑗, 𝑘−1 若有經過 𝑘

狀態/轉移方程 設定狀態 𝑠 i,j,𝑘 為 𝑖 到 𝑗 只以 1,..,𝑘 為中間點的最小成本 𝑠 i,j,𝑘 = 𝑠 𝑖, 𝑗, 𝑘−1 若無經過 𝑘 s i,𝑘, 𝑘−1 +𝑠 𝑘, 𝑗, 𝑘−1 若有經過 𝑘 𝑠 i,j,𝑘 =𝑚𝑖𝑛(𝑠 𝑖, 𝑗, 𝑘−1 , s I,𝑘, 𝑘−1 +𝑠 𝑘, 𝑗, 𝑘−1 )

邊界 𝑠 i,j,0 = 0    若 𝑖=𝑗 𝑤𝑒𝑖𝑔ℎ𝑡 𝑖, 𝑗  若有 𝑖, 𝑗 邊 ∞   若無 𝑖, 𝑗 邊

全點對最短路徑 Floyd-Warshall's Algorithm Johnson's Algorithm

Johnson's Algorithm

Johnson's Algorithm 結合了 Bellman-ford 與 Dijkstra 的演算法 其複雜度為兩個演算法複雜度相加

Johnson's Algorithm 自行研究吧

Questions?