start: 图的存储 邻接矩阵 一般适合于顶点数目不超过1k 的题目
邻接表 顶点数目大于 1k 的题目
实现 vector
实现
开一个 vector
数组 Adj[N]
其中N
为顶点个数。
遍历的伪代码 深度优先搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 DFS(u) { vis[u] = true ; for () { if (vis[vi] = false ) { DFS[vi]; } } } DFSTrave(G) { for () { if (vis[u] == false ) { DFS(u); } } }
广度优先搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <queue> ··· BFS(u) { queue q; vis[u] = true ; while (q.size() != 0 ) { int top = q.front(); q.pop(); for () { if (vis[vi] = false ) { vis[vi] = true ; q.push(vi); } } } } BFSTrave(G) { for () { if (vis[u] == false ) { BFS(u); } } }
遍历的实现 DFS 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <string.h> int n, G[maxn][maxn];bool vis[maxn];void DFS (int u, int depth) { vis[u] = true ; for (int i = 0 ;i < n; i++) { if (vis[i] ==false && G[u][v] != INF) { DFS(v, depth+1 ); } } } void DFSTrave () { for (int u = 0 ; u < n; u++) { if (vis[u] == false ) { DFS(u,1 ); } } } int main () { ··· memset (vis, 0 , sizeof (vis)); ··· }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <vector> #include <string.h>//memset 所在的库函数 vector <int > Adj[maxn];int n;bool vis[maxn];void DFS (int u, int depth) { vis[u] = true ; for (int i = 0 ; i<Adj.size(); i++) { int v = Adj[u][i]; if (vis[v] == false ) { DFS(v, depth + 1 ); } } } void DFSTrave () { for (int u = 0 ; u < n; u++) { if (vis[u] == false ) { DFS(u, 1 ); } } }
BFS 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <queue> int n, G[maxn][maxn]; bool inq[maxn] = {false };void BFS (int u) { queue <int > q; q.push(u); while (q.size != 0 ) { int top = q.front(); q.pop(); for (int i = 0 ; i < n; i++) { if (inq[i] == false &&G[u][v] != INF) { q.push(v); inq[v] = true ; } } } } void BFSTrave () { for (int u = 0 ; u < n; u++) { if (inq[u] == false ) { BFS(u); } } }
-邻接表版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <vector> #include <queue> vector <int > Adj[maxn];int n;bool inq[maxn] = {false };void BFS (int u) { queue <int > q; q.push(u); inq[u] = true ; while (!q.empty()) { int top = q.front(); q.pop(); for (int i = 0 ; i<Adj[u].size; i++) { int v = Adj[u][i]; if (inq[v] == false ) { q.push(v); inq[v] = true ; } } } } void BFSTrave () { for (int u = 0 ; u < n; u++) { if (inq[u] == false ) { BFS(u); } } }
注:当题目要求输出节点的层号时,只需将vector<>
中存储的元素换成结构体即可,结构体包含节点编号和层号。遍历时更新层号信息,子节点时父节点的层号+1
结构体如下:
1 2 3 4 5 struct node { int v; int layer; };
最短路径 dijkstra 算法 练习题:PAT A1003,A1030,A1018,A1072,A1087。