【Depth-first search】|DFS|Traversal algorithm|Deep traversal idea with edge weight 1|Solve common graph and tree problems

1. Depth-first traversal (BFS)

The idea of ​​depth-first traversal is actually a common idea of ​​complete traversal. The way we understand it is to use the idea of ​​a mouse. Every time a node appears, we nest a layer of dfs to let him carry out the code process below. The so-called When the mouse goes downstairs , when the algorithm moves on the parallel node, it means that it has completed the operation of going downstairs and has returned to perform the next operation. We call it mouse translation . To understand this BFS in this way , in fact, this BFS is also It can be seen as a large pointer to traverse back and forth.

Second, the idea of ​​depth-first traversal

There are two types of depth traversal. First, the first type is single-start traversal , and the other is multi-start traversal . Traversing with a clear starting position is relatively simple, so we generally convert some multi-start traversals into The traversal of a single starting point is converted into a single starting point traversal, simplifying the operation

First, let's learn the general idea of ​​BFS , and then learn the ideas of these two types of questions. As mentioned above, the core operation of our BFS is a recursive traversal operation, and there is a part of translation outside of this Operation Generally we use a loop to complete.

Then it is how to complete these operations to ensure that these traversals will not be repeated. First of all, we think of the bool traversal true and false method. We use this method to store whether these points have been traversed to complete the traversal operation between individual points. When this point completes the traversal operation this time, we will put it Return to the case without traversal.

There are other special judgment methods, special treatment for special situations, in general, the main idea of ​​my dfs is a nested loop and a conditional judgment to judge whether it has been traversed, and the other is the solution to the problem

Three, depth-first traversal algorithm

1, DFS for multi-point traversal

Multi-point traversal is generally a complete graph. We want to nest its traversal and record its position from 0, and the iterative operation is in the loop. This cycle is to traverse each point of this graph. Generally speaking, this kind of problem is not very obvious, but they are definitely a problem of traversal completion.

First, let's give an example of a very simple deep search sorting problem

topic description

Given an integer n, arrange numbers 1∼n in a row, there will be many ways to arrange them. Now, please output all the permutation methods in lexicographical order.

input format

A total of one line, containing an integer n.

output format

Output all permutation schemes in lexicographical order, each scheme occupying one line.

data range

1≤n≤7

Input sample:

3

Sample output:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

answer

#include <iostream>
using namespace std ;

const int N  = 10 ;

int n ;
int path[N] ; 
bool st[N]  ;

void dfs (int u )
{
    
    
	if(u == n )
	{
    
    
		for(int i = 0 ; i < n ; i ++ )
			cout << path[i] <<  " " ;
		cout << endl; 
		return ; //返回上一个结点
	}
	for(int i = 1 ; i <=  n ; i ++ )
	{
    
    
		if(!st[i]) 
		{
    
    
			path[u]  = i ; 
			st[i] = true ;
			//让下一层的判断条件和输出结果改变
			dfs(u + 1 );
			//递归到下一层
			st[i] = false ;
			//从底层返回到这一层,把相关的条件再改回来
		}
	}
	return ;
}


int main () 
{
    
    
	cin >> n ;
	dfs(0) ;
	return 0 ;
}

This is the simplest DFS operation. We know that there are many optimization operations for this operation, but this section only describes the simplest DFS operation, and then there are detailed chapters to solve other complex problems.

2. Traversal of a fixed starting point

Traversing with a fixed starting point, they generally have more complicated situations. First of all, they may have some fixed paths or more complex content coverage, which generally appear in trees or graphs. Then we first understand the tree , and the storage of the graph will complete this part of the study.

The following code is a fixed-point dfs operation using the graph as an example

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std  ;

const int N = 100010 ;

int n ; 
int ans = N ; 
int e[N * 2] ,ne[N * 2] , h[N] , idx ; 
bool st[N] ;



void add (int a, int b )
{
    
    
	e[++ idx] = b, ne[idx] = h[a] , h[a] = idx ; 
}


int dfs (int u )
{
    
    
	st[u] = true ; 
	int sum = 0 , size = 0 ;
	for(int i = h[u] ; i != - 1 ; i = ne[i])
	{
    
    //向下遍历
		int j = e[i] ;
		if(!st[j]) 
		{
    
    
		int s = dfs(j) ;
		sum += s ; 
		size = max (size , s ) ;
	}
	}
		size = max (n - sum - 1 ,size) ;
	ans = min (ans ,size ) ;
	return sum + 1 ;
}
int main ()
{
    
    memset(h , - 1 , sizeof h) ;
	cin >> n ;
	for(int i = 1 ; i < n ; i ++) 
	{
    
    
		int a , b ;
		cin >> a >> b ;
		add(a , b) ;
		add(b , a) ;
	}
	dfs(1);//首先从固定点开始操作
	cout << ans << endl ;
	return 0 ;
}

3. Establishment of graphs and trees

Trees and graphs are the main objects of search , so it is necessary for us to understand the establishment of search and the realization of related processes. There are roughly two ways to store them. The first is the so-called adjacency list. We use the relationship between their vertices to create a matrix, use this matrix to store data, and the storage method of the adjacency list. It is in each After the vertex, a linked list is created to simulate whether a certain vertex can be reached.
insert image description here
Now we mainly use the trees and graphs created by critical matrices

1, the creation of trees and graphs
#include <iostream>
#include <algorithm>
using namespace std ;

const int N = 1000010 ;
//存储顶点的数量
const int M  =2000020 ;
//存储边的数量

int h[N];
//树的顶点

int e[N],ne[N],idx ; 
//边的存储


int main ()
{
    
    
	memset( h , - 1 , sizeof h );
	return 0 ;
}

2. Edge creation

void add(int a,int b )
{
    
    
	e[++ idx] = b , ne[idx] = h[a] , h[a] = idx ; 
}

Four, a simple template for deep traversal

#include <iostream>
using namespace std ;

void dfs (层数,其他遍历判断参数)
{
    
    
	if(出局判断)
	{
    
    
		//在某个时刻完成答案的输出
		return ;
		//返回上一层
	}
	for(枚举下一层的可能的数据)
	{
    
    
		if(当这个位置能用的时候)
		{
    
    
			//改变参数
			dfs(层数 + 1)
			//改回参数
		}
	}
	return ;// 返回上一层
}
int main ()
{
    
    
	return 0 ; 
}

Guess you like

Origin blog.csdn.net/wen030803/article/details/131811237