See a problem, the problem solution summarizes the bfs and dfs templates to record.
1: bfs
bfs is accessed layer by layer, which is suitable for finding the shortest path steps with goals. Think about searching layer by layer, and each layer represents one step. bfs gives priority to sibling nodes (adjacent nodes). Only when this layer is fully accessed can it access the next layer, that is, the bfs layer represents the current location (node)
2: dfs
DFS is implemented by recursion. It gives priority to searching depth and then backtracking. Priority access is given to child nodes that have not been accessed. DFS is mostly used for connectivity problems. Because its operation idea is very similar to that of human brain, it is more natural to solve connectivity problems.
The following is a simple framework for bfs and dfs
1: bfs
Template:
First://bfs template struct ed { ..... } deque<ed>q;//Of course, you can also use queue void bfs() { Mark start point Start in queue while(!q.empty())//Queue is not empty { ed nw=q.front();//Return to the head of the team for(Expand the next possible state) { ed nxt; Record this status Judge whether the status is legal Tag status q.push_back(nxt);//Status queued } q.pop_front();//Pop up team leader } } Second: /** * Breadth first search * @param Vs starting point * @param Vd End */ bool BFS(Node& Vs, Node& Vd){ queue<Node> Q; Node Vn, Vw; int i; //The initial state puts the starting point into the queue Q Q.push(Vs); hash(Vw) = true;//The setting node has been accessed! while (!Q.empty()){//The queue is not empty, continue searching! //Take out the header Vn of the queue Vn = Q.front(); //Remove from queue Q.pop(); while(Vw = Vn A node that can be reached by a rule){ if (Vw == Vd){//Found the end! //Record the path. There is no solution here return true;//return } if (isValid(Vw) && !visit[Vw]){ //Vw is a legal node and is a white node Q.push(Vw);//Join queue Q hash(Vw) = true;//Set node color } } } return false;//unsolvable }
2: dfs
Template:
First://It is also a time to go to the end, and then go back void dfs() { for(Expansion state) { Legal judgment record dfs(Keep searching); to flash back; } } */ Second: void dfs(){ Search whether the upper, lower, left and right positions meet the conditions. if((qualified) { sign dfs() } }
Record a question according to the template for easy understanding
Title:
A rectangular array is composed of numbers ^ 00 ^ 99 ^ and numbers ^ 11 ^ 99 ^ represent cells. The definition of cells is up, down, left and right along the cell number. If it is still a cell number, it is the same cell. Calculate the number of cells of a given rectangular array.
Input format
The two integers in the first row represent the matrix sizes {nn} and {mm.
Next, a string containing only characters ¢ 0 ¢ to ¢ 9 ¢ with a length of ¢ mm , represents the ¢ n \times mn × The matrix of m.
Output format
An integer in a row represents the number of cells.
Input and output samples
Enter #1
4 10 0234500067 1034560500 2045600671 0000000089
Output #1
4
In fact, the idea is very simple. In order to facilitate understanding, I specially marked the number 0 in red. It was found that there are only four connected blocks wrapped by the number 0.
The first is the solution of bfs:
#include<iostream> #Include < deque > / / bidirectional queue header file using namespace std; struct pp { int x, y; };//Initialization function deque<pp> q;//queue int n, m, ans = 0;//n rows, m columns, ans is the answer int a[105][105];//Storage matrix bool used[105][105];//Record whether you have passed int dx[4] = { -1,1,0,0 };//Take a step up, down, left and right, line number and list the changes int dy[4] = { 0,0,-1,1 }; void bfs(int sx, int sy)//bfs { pp st; st.x = sx; st.y = sy; used[sx][sy] = 1; q.push_back(st); while (!q.empty()) { pp nw = q.front(); for (int i = 0; i < 4; i++) { pp nxt = nw; nxt.x += dx[i]; nxt.y += dy[i]; if (a[nxt.x][nxt.y] == 0 || used[nxt.x][nxt.y] == 1) continue;//If it's zero, don't worry about him used[nxt.x][nxt.y] = 1;//Dye the dots of this connecting block q.push_back(nxt); } q.pop_front();//Because it's a two-way queue. This allows the traversed number to go out } } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%1d", &a[i][j]);//Traverse map for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (used[i][j] == 0 && a[i][j] != 0) { bfs(i, j); ans++;//If you haven't searched ans in this connection++ } } } cout << ans; return 0; }
Secondly, the dfs method, because they are connected blocks, the difference is not too large
#include<iostream> using namespace std; int n, m, ans = 0; int a[105][105]; bool used[105][105]; int dx[4] = { -1,1,0,0 }; int dy[4] = { 0,0,-1,1 }; void dfs(int x, int y) { used[x][y] = 1; for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (a[nx][ny] == 0 || used[nx][ny] == 1) continue; dfs(nx, ny);//to flash back } } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%1d", &a[i][j]);//Traverse map for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (used[i][j] == 0 && a[i][j] != 0) { dfs(i, j); ans++;//Find connected blocks } } } cout << ans; return 0; }
in short
One focuses on queues, the other on backtracking, well, that's it.