图论
存储。图用邻接矩阵(较少),树用邻接表。
1 2
| void add(int a, int b) {e[idx]=b; ne[idx]=h[a]; h[a]=idx++;}
|
一、遍历:DFS和BFS
DFS模板
dfs多用函数递归,作为遍历框架;bfs则用队列是否为空的循环,作为遍历框架。
1 2 3 4 5 6 7 8 9 10 11 12 13
| void dfs(int u){ if(u==n) for(int i=1; i<=n; i++){ if(!st[i]){ path[u]=i; st[i]=true; dfs(u+1); path[u]=0; st[i]=false; } } }
|
1 2 3 4 5 6 7 8 9 10
| void dfs(int u){ st[u]=trrue; for(int i=h[u]; i!=-1; i=ne[i]){ int j=e[i]; if(!st[j]){ dfs(j); } } }
|
经典例题
N皇后问题
BFS模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void bfs(){ queue<int> q; unordered_map<string,int> d; q.push({1,1}); while(q.size()){ auto t=q.front(); q.pop(); if(d[t]满足条件) return d[t]; int distance; for(int i=h[t]; i!=-1; i=ne[i]){ int j=e[i]; if(!st[j]){ d[t]=distance+1; q.push(t); } } } }
|
二、拓扑排序
1 2 3 4 5 6 7 8 9 10 11
| void top_sort(){ queue<int>q; for(int i=1; i<=n; i++) {if(!in[i]) q.push(i);} while(q.size()){ auto t=q.front(); q.pop(); L.push_back(t); for(int i=h[t]; i!=-1; i=h[i]){ int j=e[i]; if(--in[j]==0) q.push(j); } } }
|
( 还不会拓扑排序?看这一篇就够了_Iareges的博客-CSDN博客)
例题
有向图的拓扑序列
三、最短路
Djkstra
1使用于紧密矩阵,2适用于稀疏矩阵。
- 连线很多的时候,对应的就是稠密图,显然易见,稠密图的路径太多了,所以就用点来找,也就是抓重点;
- 点很多,但是连线不是很多的时候,对应的就是稀疏图,稀疏图的路径不多,所以按照连接路径找最短路,这个过程运用优先队列,能确保每一次查找保留到更新到队列里的都是最小的,同时还解决了两个点多条路选择最短路的问题;
```C++