<style type="text/css"> .slides { text-align: left !important; } </style> # 基礎圖論 #### Author:H1de_on_bruH ---- ## 概要 圖的構成 怎麼存圖? 圖的遍歷:DFS與BFS --- ## 甚麼是圖論? ---- 維基百科: >圖論(英語:graph theory),是組合數學分支,和其他數學分支,如群論、矩陣論、拓撲學有著密切關係。圖是圖論的主要研究對象。 ---- ## 圖的組成 ---- 構成各種圖的基礎元素有節點和邊 如下圖 ![](https://i.imgur.com/PNkqZ2J.png) ---- **是的這個也算圖** ![](https://i.imgur.com/FecGg6G.png) ---- 圖有分 - 有向/無向 - 連通/不連通 - 簡單/不是簡單 (無重邊和自環) - 帶權/不帶權 --- ## 圖的儲存 ---- 現在你知道甚麼是圖了 那要到底要怎麼儲存這張圖呢? ---- ### 相鄰矩陣(adjacent matrix) ---- 開一個$N\times N$的二維陣列 若有一邊從$i$連到$j$且長為$x$ 那就把$a_{i,j}$設成$x$ ---- **優點:** $O(1)$時間查找任意$x,y$間的邊的資訊,拆邊,建邊 ---- **缺點:** $O(V^2)$空間複雜度(V表節點數) 不能建重邊 ---- ### 邊表(edge list) ---- 開一個$N$的std::vector陣列 ```cpp= vector<int> adj[n] ``` 如果有一邊從$i$連到$j$ 就在`adj[i]`裡面`push_back`一個`j` ---- **優點:** $O(E)$空間複雜度(E表邊數) $O(1)$時間建邊 可以建重邊 ---- **缺點** $O(E)$拆邊,查找邊 ---- ## 圖的遍歷 ---- **怎麼走?** --- ### DFS(深度優先) ---- 找一個點開始走 一直往下找一個沒走過的點走 若且唯若你在這個點沒有連結到其他未走過的點時 回朔的上一個節點 並往另一條路走 以此類推 ```cpp= void dfs(int now) { vis[now]=1; for(int i:path[now]) if(vis[i]==0) dfs(i); } ``` ---- https://www.cs.usfca.edu/~galles/visualization/DFS.html ---- 好處:好寫+可以蓋出 dfs tree ---- ![image](https://hackmd.io/_uploads/S1uzg5Tra.png) ---- ### [CF:1139C - Edgy Trees ](https://codeforces.com/problemset/problem/1139/C) 給你一顆$n$個節點的樹($n$個點$n-1$個邊並且所有點相連通) 有紅邊跟黑邊 要找出有幾個長度為$k$的"好的"行程 **只要$1\le i\le k-1$中 有一個$a_i$到$a_{i+1}$($a_i$可以等於$a_{i+1}$)的簡單路徑中有經過黑色的邊就算是好的行程** ---- 總共有$n^k$種行程 現在只要再找有幾種行程不是好的就可以求出答案了 一開始建圖的時候不要把黑邊建進去 那不好的行程只剩下各個$(連通塊的大小)^k$的總和 ---- #### 其他例題 [CF:580C - Kefa and Park ](https://codeforces.com/problemset/problem/580/C) [ATC:RGB Coloring 2](https://atcoder.jp/contests/abc199/tasks/abc199_d) --- ### BFS(廣度優先) ---- 找一個點開始 把周圍的點一個一個放進"待辦清單"的最尾端 再往清單中第一個點走下去 並把他周圍還沒走到的點也放到清單的尾端 再往清單中下一個點走下去 以此類推 ```cpp= queue<int>q,q.push(1),vis[1]=1; while(q.size()) { int now=q.front(); q.pop(); for(int i:path[now]) if(!vis[i]) vis[i]=1,q.push(i); } ``` ---- https://www.cs.usfca.edu/~galles/visualization/BFS.html ---- 好處:如果從 $v$ 開始遍歷則遍歷的順序會依照 $v$ 到各個點的距離。 ---- #### [TIOJ 1572](https://tioj.ck.tp.edu.tw/problems/1572) 非常簡單的BFS裸題 比較麻煩的就是要求最小路徑中字典序最小的那條路徑 ---- 有興趣看實作的可以點下面的連結 https://pastebin.pl/view/5f91e5f6 --- ## 總結 ---- BFS跟DFS都是很基礎但都是很重要的演算法 很多演算法都是從這兩者之間演化出來的 請務必多練習多熟悉 ----
{"metaMigratedAt":"2023-06-16T09:29:14.812Z","metaMigratedFrom":"YAML","title":"基礎圖論","breaks":true,"slideOptions":"{\"theme\":\"black\",\"transition\":\"slide\"}","description":"圖的構成怎麼存圖?圖的遍歷:DFS與BFS","contributors":"[{\"id\":\"b6728096-4c9a-4b93-9b51-70c56850e20f\",\"add\":6968,\"del\":2616},{\"id\":\"25d6f561-7fc8-4c0b-8638-c8ad8a1c8b75\",\"add\":58,\"del\":330},{\"id\":\"f6c1f4c6-eaa6-44aa-a181-7ce7c40dc9d5\",\"add\":397,\"del\":2015}]"}
    1256 views
   Owned this note