圖論理論基礎
https://www.programmercarl.com/kamacoder/圖論理論基礎.html#圖的基本概念
深度優先搜尋理論基礎
https://www.programmercarl.com/kamacoder/圖論深搜理論基礎.html#深搜三部曲
98.所有可達路徑
https://kamacoder.com/problempage.php?pid=1170
程式碼隨想錄
https://www.programmercarl.com/kamacoder/0098.所有可達路徑.html
廣度優先搜尋理論基礎
https://www.programmercarl.com/kamacoder/圖論廣搜理論基礎.html
圖論基礎
-
圖種類
- 有向圖和無向圖;
- 加權無向圖和加權有向圖;
-
度
- 無向圖:邊的個數
- 有向圖:入度(指向該節點的個數) 和 出入 (從該節點出發的個數)
-
連通性
- 無向圖-連通圖:任何節點都可以達到;
- 有向圖- 強連通圖:任何兩個節點可以互相達到;
-
連通分量
- 在無向圖中:極大連通子圖就是該圖的連通分量;如下圖的(1,2,5)節點和(3,4,6)節點;
- 強連通分量:有向圖中,極大強連通子圖稱之為該圖的強連通分量;如下圖(6,7,8)和(1,2,3,4,5)的圖;
- 在無向圖中:極大連通子圖就是該圖的連通分量;如下圖的(1,2,5)節點和(3,4,6)節點;
-
圖的構造
- 鄰接表;鄰接矩陣;類;
- 樸素儲存;鄰接表;鄰居矩陣;
-
鄰接矩陣
- 二維陣列表示圖結構;
- 節點表示圖
- grid[2][5]=6 grid[5][2]=6 說明grid中2和5節點中有一邊;
-
鄰接表
- 陣列+連結串列;
- 從邊的角度儲存圖
圖的遍歷方式
- 深度優先搜尋(dfs)
- 廣度優先搜尋(bfs)
深度優先搜尋理論基礎
概念
- 向一個方向搜尋,遇到絕境就回溯,繼續;
程式碼框架
- 因為有路徑回溯和路徑選擇;
- 所以是遞迴+回溯的過程;
void dfs(引數) {
if (終止條件) {
存放結果;
return;
}
for (選擇:本節點所連線的其他節點) {
處理節點;
dfs(圖,選擇的節點); // 遞迴
回溯,撤銷處理結果
}
}
深搜三部曲
- 確認遞迴函式、引數;
void dfs(引數)
- 二維陣列儲存所有路徑;路徑以一維陣列保持;
- 全域性變數儲存
- 確認終止條件;
if (終止條件) {
存放結果;
return;
}
- 處理目前搜尋節點出發的路徑;
for (選擇:本節點所連線的其他節點) {
處理節點;
dfs(圖,選擇的節點); // 遞迴
回溯,撤銷處理結果
}
98. 所有可達路徑
題解
採用鄰接矩陣方式
- 該方式採用鄰接矩陣方式儲存資料
- 嚴格按照模版進行遍歷
點選檢視程式碼
```python
def dfs(graph,x,n,res,path):
if x==n:
res.append(path.copy())
return
for i in range(1,n+1):
if graph[x][i]==1:
path.append(i)
dfs(graph,i,n,res,path)
path.pop()
def main():
n,m = map(int,input().split())
graph =[[0]*(n+1) for _ in range(n+1)]
for i in range(m):
s,t = map(int,input().split())
graph[s][t] = 1
path = [1]
res = []
dfs(graph,1,n,res,path)
if not res:
print(-1)
return
for path in res:
print(" ".join(map(str,path)))
if __name__ == '__main__':
main()
```
</details>
採用鄰接列表方式
-
採用 from collections import defaultdict方式
點選檢視程式碼
from collections import defaultdict def dfs(graph,x,n,path,res): if x==n: res.append(path.copy()) return for i in graph[x]: path.append(i) dfs(graph,i,n,path,res) path.pop() def main(): n,m = map(int,input().split()) graph = defaultdict(list) for i in range(m): s,t = map(int,input().split()) graph[s].append(t) # print(graph) res = [] path = [1] dfs(graph,1,n,[1],res) if not res: print(-1) else: for path in res: print(" ".join(map(str,path))) if __name__ == '__main__': main()
廣度優先搜尋理論基礎
使用場景
- 解決兩點之間的最短路徑問題
- 不涉及具體遍歷方式,只要把相鄰和相同屬性的節點標記上即可;
廣搜過程
- 一圈一圈搜尋