图的存储
直接存边(邻接表)
1 2 3 4 5 6 7 8 int n,k;cin>>n>>k; vector<vector<int >> graph (n+1 , vector <int >()); for (int i = 0 ; i < k; i++) { int a, b; cin >> a >> b; graph[a].push_back (b); }
这种方法的优点是简单,但难以判断两个顶点之间是否有边相连。
邻接矩阵
1 2 3 4 5 6 7 8 int n, k;cin >> n >> k; vector<vector<int >> graph (n+1 , vector <int >(n+1 , 0 )); for (int i = 0 ; i < k; i++) { int a, b; cin >> a >> b; graph[a][b] = 1 ; }
这种方法的优点是可以快速判断两个顶点之间是否有边相连,但空间复杂度较高。
DFS
邻接矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 void dfs (vector<vector<int >>& graph, vector<bool >& visited, int start) { if (visited[start]) return ; visited[start] = true ; for (int i = 1 ; i <= n; i++) { if (graph[start][i] == 1 && !visited[i]) { dfs (graph, visited, i); } } } int main () { }
邻接表
1 2 3 4 5 6 7 8 9 10 11 12 13 void dfs (vector<vector<int >>& graph, vector<bool >& visited, int start) { if (visited[start]) return ; visited[start] = true ; for (int i: graph[start]) { if (!visited[i]) { dfs (graph, visited, i); } } } int main () {}
BFS
邻接矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void bfs (vector<vector<int >>& graph, int start) { queue<int > q; vector<bool > visited (n+1 , false ) ; q.push (start); visited[start] = true ; while (!q.empty ()) { int cur = q.front (); q.pop (); for (int i = 1 ; i <= n; i++) { if (graph[cur][i] == 1 && !visited[i]) { q.push (i); visited[i] = true ; } } } } int main () {}
邻接表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void bfs (vector<vector<int >>& graph, int start) { queue<int > q; vector<bool > visited (n+1 , false ) ; q.push (start); visited[start] = true ; while (!q.empty ()) { int cur = q.front (); q.pop (); for (int i: graph[cur]) { if (!visited[i]) { q.push (i); visited[i] = true ; } } } } int main () {}
总结
DFS适合用于寻找连通性,寻找环等。
BFS适合用于寻找最短路径。
无论哪种方法,都可以遍历整个图。
这里的两种图的存储方式,邻接表和邻接矩阵,可以根据实际情况选择。