Depth first traversal of trees and graphs & breadth first traversal of trees and graphs
The two traversal methods of tree and graph are algorithms based on the idea of dfs and bfs. Its idea is still recursive, but the traversal object becomes an undirected graph, so there are more precautions in the process of graph construction and search.
1, Depth first traversal of trees and graphs
Depth first traversal is similar to dfs, which traverses the branches in the tree and graph in turn.
1. Structure
Because it is an undirected graph, it is different from ordinary trees. First, look at the code:
int e[N],ne[N],h[M];//M = 2 * N; int idx; void daa(int a,int b) { e[idx] = b,ne[idx] = h[a],h[a] = idx++; }
When entering:
int a,int b; cin >> a >> b; add(a,b),add(b,a);
Because it is an undirected graph, it needs to add twice. A closer look shows that the add function is similar to the function of inserting the header node of a single linked list. The following is the code of inserting the header node of a single linked list:
void head_add(int x) { e[idx] = x,ne[idx] = head,head = idx++; }
Just replace the head with an h array.
In undirected graphs, h and NE arrays play similar but different roles. H is the pointer to the child node, which is used for the recursive part; When ne searches to the end, it jumps back to the pointer of another child node of the previous bifurcation for circulation.
2. Traversal
Code of dfs function:
void dfs(int u) { vis[u] = 1; for(int i = h[u];i != -1;i = ne[i]) { int j = e[i]; if(vis[j])continue; int s = dfs(j); } }
When facing different problems, you can make certain modifications.
3. Example code
Here is an example: 846. The center of gravity of the tree - AcWing question bank
The code is as follows:
#include<iostream> #include<cstring> using namespace std; const int N = 1e5 + 3, M = N * 2; int n, e[M], ne[M], h[N], idx; bool vis[N]; int ans = N; void add(int a, int b) { e[idx] = a, ne[idx] = h[b], h[b] = idx++; } int dfs(int u) { vis[u] = 1; int sum = 1, rex = 0; for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (vis[j]) continue; int s = dfs(j); rex = max(rex, s); sum += s; } rex = max(rex, n - sum); ans = min(ans, rex); return sum; } int main() { memset(h, -1, sizeof h); cin >> n; for (int i = 0; i < n - 1; i++) { int a, b; cin >> a >> b; add(a, b), add(b, a); } dfs(1); cout << ans << endl; return 0; }
2, Breadth first traversal of trees and graphs
The idea of breadth first traversal is similar to bfs, which searches layer by layer.
1. Build
The construction method is the same as depth first traversal
2. Traversal
Breadth first traversal is the search for the edge, and the code is as follows:
void bfs() { int hh = 0,tt = 0; q[0] = 1;//Queue array while(hh <= tt) { int t = q[hh++]; for(int i = h[t];i != -1;i = ne[i]) { int j = e[i]; if(judge) q[++tt] = j; } } }
Its basic template is like this. If you want to achieve different results, you can fill in the corresponding code.
3. Example code
Such as: 847. The level of the point in the figure - AcWing question bank
The code is as follows:
#include<iostream> #include<cstring> using namespace std; const int N = 1e5 + 3,M = N * 2; int n,m,idx; int e[M],ne[M],h[N]; int q[N],d[N]; void add(int a,int b) { e[idx] = b,ne[idx] = h[a],h[a] = idx++; } int bfs() { int hh = 0,tt = 0; q[0] = 1; memset(d,-1,sizeof d); d[1] = 0; while(hh <= tt) { int t = q[hh++]; for(int i = h[t];i != -1;i = ne[i]) { int j = e[i]; if(d[j] == -1) { q[++tt] = j; d[j] = d[t] + 1; } } } return d[n]; } int main() { scanf("%d%d",&n,&m); memset(h,-1,sizeof h); for(int i = 0;i < m;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); } cout << bfs() << endl; return 0; }