Deep search (DFS)

Depth-first search - do not hit the brick wall does not look back

Deep traversal search is or as a graph and tree search algorithms.

Idea: do not hit the brick wall does not look back!

Selecting a first non-access point as the source node. Choose a path from the source node has gone down, along the edge of the current vertex, access to this route until you go elsewhere so far. Then return to the previous vertex, continue to test the remaining sub-vertex access this vertex, until the current sub-vertex vertex have been visited, then return to the previous vertex, continue to repeat. In order to achieve traversal.

To a simple example of simulation DFS:

(First of all, we left the default preference or accessed by elements under)
Here Insert Picture Description
selected as the source node A ------> (continue to the next level deep search) access to the B -------> (Continue the next layer deep search) access to the D ------> (continued next deep search) searched C ------> (this time to discover all the next node C have already been visited) Back C to node D (because it is accessible from D to C to, so do not go back on the other node C) ------> D we re-iterate the other child nodes E ----- -> (E found no child node) to return to a node D ------> (node D does not find the child access) is returned B ------> (child node B have not been accessed ) returns a ------> (a child nodes no non-accessed) completed the DFS
Thus, this figure search deep traversal order: A-> B-> D-> C- > E

Summarize deep search of ideas: along a path traversal, until the end, and then back again to traverse the other path (do not go through the fork in the road) to do the same traverse until all nodes have been visited, that is, back to the source node and child node of the source node has no unvisited.

For example : the number of full permutation problem, a number of inputs n, 1-n outputs the full array.
Do the following analysis:

We abstract the problem: that is, there are numbers 1-n, respectively n boxes to put a fixed one's asking what are the different release method.
Here Insert Picture Description

The idea of using deep search (do not hit the brick wall does not look back):
First, we default priority placed smallest small digital ----- This step is equivalent to or choose to go first on the lower left of the road.
Start placing: 1 in the first, second ··· n 2 is placed on the n-th, we have come to the head, all the boxes we let figures. Back step and the n-th number n taken box, we currently in the n-1 at the boxes. The current release of the box is n-1 this figure, we take it out. At this time, our hands have n-1 and n two numbers. Using the principle of placing the minimum number, but this number n-1 just taken out of the box. To avoid duplication, you can not recapture go. Therefore, the number of unplaced current in addition to the minimum number of n n-1, n-1 into the first one inside the box, then go down, go to the n-th box, a digital left hand n- 1, the n-th NATURAL placed.
At this point we already have two arrangements:
, 2, 3, · · ·, n-1, n and 1,2,3, ···, n, n- 1
continues to back: The current in the n-th box , we went to the back of the n-1 boxes (and remove the n-th box number n-1), we found that these two figures are let go in the first n-1 box, it will only back up again (the way pick up the n-1 n-number boxes), went to the n-2-boxes, the box number remove n-2. Currently, our state, on n-2-boxes, digital hand, n-2, n-2, n-; then put a small follow the principle, and can not be repeated, this number to n-1 into n- the box 2, continue to go down, first n-2 n-1 into the first box, so that the n-th number n of the discharge box.
At this time, an arrangement has emerged:
1,2,3, ?????, n-1, n-2, n;
again back from the n to n-1 cassette box: Similarly produced 1,2,3 , ···, n-1, n , n-2 are arranged
because it can not go down, only back again to the n-2-boxes, into n, ········
Repeating the above operations, it will eventually go back to the first box, the first box after the maximum number n are done and, again back to the first box, the first box has been unable to put other figures. And that is the end of the whole arrangement.

Attach the complete code for this problem:

#include <stdio.h>
int a[101];//盒子,目前只能放最多100个盒子,你可以自己加,但是要同时修改book的个数 
int book[101]={0};//标记数组,标记是否已经放入 
void dfs(int step,int n)//当前在第几个盒子上,总共有多少数 
{
	int i;
	if(step==n+1){//如果站在第n+1个盒子面前了,那说明,已经放好所有的了 
		for(i=1;i<=n;i++){//输出这个组合 
			printf("%d ",a[i]);
		}
		printf("\n");
		return;//返回上一层,也就是调用它的地方 (回溯) 
	}
	for(i=1;i<=n;i++){//遵循最小原则  放入数字 
		//判断数字是否已经放入到之前的盒子
		if(book[i]==0){//数字并未放入 
			a[step]=i;//放入
			book[i]=1;//标记已经放入 
			//继续需要往下一个盒子走
			dfs(step+1,n); 
			//走完这个盒子之后的所有操作,已经又回溯到这个盒子了,马上就要在此盒子放入下一个数了,所以我们需要将刚才的数字收回 
			book[i]=0; 
		} 
	} 
	return;
} 
int main(){
	int n;
	scanf("%d",&n);
	dfs(1,n);
	return 0;
} 

Through the above, the basic model can be summed up deep search of:

void  dfs(int  step)//当前状态
{
	//判断边界条件
	if(xxx){
		return//返回上一步
	}
	//尝试每一种可能
	for(xxx){
		//判断是否符合条件
		if(xxx){
			//继续走下一步
			dfs(step+1);
		}
	}
	return//全部遍历做完后返回
}

Into the classic -----> DFS solve the maze
labyrinth has n rows and m columns of cells, each cell is either open space or an obstacle, find a shortest path from the beginning to the end.
Enter the maze maps and coordinates the whole story.
FIG example is:
Here Insert Picture Description
diamond as a start point, the end point of the heart shape, Star of David obstacle. Our solution is, from the starting point, search deep down, every time they go into the search further concessions to the number of +1, search history, a few steps down when the heart-shaped, and the step back, searching another path. Until search finished.
There are four directions (up and down) analysis that, every time we go into the traverse. We imitate the basic model of deep search:

void  dfs(int x,int y,int  step)//当前状态
{
	int next[4][2]={{0,1},//向右 
				{1,0},//向下 
				{0,-1},//向左 
				{-1,0}};//向上
	int tx,ty,i;
	//判断边界条件
	if(x==p&&y==q){//走到了终点 
		if(step<min){
			min=step;
		} 
		return;//返回上一步
	}
	//尝试每一种可能(枚举四种走法) 
	for(i=0;i<4;i++){
		//计算下一点坐标 
		tx=x+next[i][0];
		ty=y+next[i][1];
		//判断是否符合条件(下一点坐标是否超范围,是否是障碍物或已在路径中) 
		if(tx<1||ty<1||tx>n||ty>m){//超范围,则continue下一种走法 
			continue; 
		}
		//可以思考一下为何不把超范围和下一个判断条件放在一起呢 ??? 
		if(book[tx][ty]==0&&a[tx][ty]==0){//是否是障碍物或已在路径中,0代表通畅,1代表障碍 
			book[tx][ty]=1;//标记 
			//继续走下一步
			dfs(tx,ty,step+1);
			book[tx][ty]=0;//消除标记 
		} 
		
	}
	return;//全部遍历做完后返回
}

Complete code:

#include <stdio.h>
int a[51][52];//地图 
int book[52][52];//标记 
int n,m,p,q,min=99999999;//m,n为地图大小,p,q为终点,min表示最短距离 
void  dfs(int x,int y,int  step)//当前状态
{
	int next[4][2]={{0,1},//向右 
					{1,0},//向下 
					{0,-1},//向左 
					{-1,0}};//向上
	int tx,ty,i;
	 
	//判断边界条件
	if(x==p&&y==q){//走到了终点 
		if(step<min){
			min=step;
		} 
		return;//返回上一步
	}
	//尝试每一种可能(枚举四种走法) 
	for(i=0;i<4;i++){
		//计算下一点坐标 
		tx=x+next[i][0];
		ty=y+next[i][1];
		//判断是否符合条件(下一点坐标是否超范围,是否是障碍物或已在路径中) 
		if(tx<1||ty<1||tx>n||ty>m){//超范围,则continue下一种走法 
			continue; 
		}
		//可以思考一下为何不把超范围和下一个判断条件放在一起呢 ??? 
		if(book[tx][ty]==0&&a[tx][ty]==0){//是否是障碍物或已在路径中,0代表通畅,1代表障碍 
			book[tx][ty]=1;//标记 
			//继续走下一步
			dfs(tx,ty,step+1);
			book[tx][ty]=0;//消除标记 
		} 
		
	}
	return;//全部遍历做完后返回
}
int main(){
	int i,j,sx,sy;//i,j用于循环,sx,xy表示初始坐标
	scanf("%d %d",&n,&m);//输入地图大小
	//读入迷宫地图 ,0代表通畅,1代表障碍 
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
		}
	} 
	scanf("%d %d %d %d",&sx,&sy,&p,&q);//输入起始和结束坐标
	book[sx][sy]=1;//起点已经在路径中 
	dfs(sx,sy,0);//从起点深搜 
	printf("%d",min); 
	return 0 ;
}

Note: Note that the code search when deep whether to cancel the mark.

Published 10 original articles · won praise 1 · views 181

Guess you like

Origin blog.csdn.net/Huberyxiao/article/details/105017214