DFS与BFS

在信息学中,有两种基础的搜索算法,它们分别为--DFS与BFS(深搜与广搜)。

DFS

DFS(Depth First Search)深度优先算法,是一种用于遍历或搜索树或图的算法,也可用于统计路径数量和解决全排列问题等。

DFS会在搜索时以深度为主,在一条路径到头后再次回溯,寻找其他路径。

核心思想

DFS的核心思想为递归回溯

递归

递归通俗来讲就是一个函数自己调用自己

举个例子:P5739 【深基7.例7】计算阶乘

普通解法:

#include<bits/stdc++.h>
using namespace std;
int n;
int ans=1;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		ans*=i;
	}
	cout<<ans;
	return 0;
}

递推解法:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=17; 
int n;
ll f[N];
int main(){
	cin>>n;
	f[1]=1;
	for(int i=2;i<=n;i++){
		f[i]=f[i-1]*i;
	}
	cout<<f[n];
	return 0;
}

递归解法:

#include<bits/stdc++.h>
using namespace std;
int jc(int x){
	if(x==1)return 1;
	return x*jc(x-1);
}
int a;
int main(){
	cin>>a;
	cout<<jc(a);
	return 0;
}

 递归图:

 在递归中,一个问题会被分解为一个又一个更小的问题,直到到达基准情况(比如此题中的return 1),在到达基准情况后,又会一层一层的向回回返,这个过程就叫做回溯。

回溯

举一个经典的例子:

从前有座山,山中有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:“ 从前有座山,山中有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:“ 从前有座山,山中有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:“ 从前有座山,山中有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:“太困了不讲了”,于是都回去睡觉了。”于是都回去睡觉了。”于是都回去睡觉了。”于是都回去睡觉了。

 写成代码就是:

#include<bits/stdc++.h>
using namespace std;
void cq(int x){
	cout<<"从前有座山,山中有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:“";
	if(x==1){
	cout<<"太困了不讲了";
	return;
	}
	cq(x-1);
	cout<<"于是都回去睡觉了。”";
    return;
}
int main(){
	cq(4);
}

"于是都回去睡觉了。”"就是代码的回溯部分。

DFS执行过程

DFS的执行过程如下:

c++模板:

#include<bits/stdc++.h>
using namespace std;
void DFS(参数){
	if(跳出条件){
		执行语句;
		return;	
	}
	标记语句;
	for(遍历){
		if(判断状态合法)continue;
		标记;
		DFS(参数); 
		取消标记; 
	} 
}
int main(){
	DFS(参数);
	return 0;
}

DFS举例

以下以洛谷原题P1596 [USACO10OCT] Lake Counting S为例:

洛谷题面:

c++代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
string s;
int tc=0;
int mov[8][2]={{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,1},{1,-1},{-1,-1}};//移动数组 
int ma[105][105];//地图 
void print(){//输出测试 
	for(int i=0;i<=n+1;i++){
		for(int j=0;j<=m+1;j++){
		cout<<setw(6)<<ma[i][j];
		}
		cout<<endl;
	}
}
void dfs(int x,int y){
	if(x>n||y>m||x<1||y<1||ma[x][y]!=0){//判断越界和已访问 
		return;
	}
	ma[x][y]=tc;//标记 
	for(int i=0;i<8;i++){//遍历位置 
		int dx=x+mov[i][0];
		int dy=y+mov[i][1];
		dfs(dx,dy);
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){//转化地图 
		cin>>s;
		for(int j=1;j<=m;j++){
			string b;
			b=s[j-1];
			if(b=="w"){
				ma[i][j]=0;
			}
			if(b=="."){
				ma[i][j]=-1;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(ma[i][j]==0){//找到新水坑 
				tc++;//增加水坑数 
				dfs(i,j);//开始深搜水坑范围 
			}
		}
	}
	cout<<tc;//输出水坑数 
//	print();
	return 0;
}

推荐题目:

 P1123 取数游戏(需要一些特殊方法)

P1219 [USACO1.5] 八皇后 Checker Challenge(需要数组判断斜行)

P6207 [USACO06OCT] Cows on Skates G(路径存储)

如果这些你都会的话,可以挑战一些较难题:

P2919 [USACO08NOV] Guarding the Farm S

BFS

BFS(Breadth First Search)广度优先算法除了遍历以及搜索之外,还可以用来搜索最短路。

BFS会同时拓展所有处在同一批次的路径。

核心思想

BFS主要依靠于队列,将同一批次的点同时扩大,可以用来搜索最短路。

执行过程

执行过程如下:

c++模板:

#include<bits/stdc++.h>
using namespace std;
queue<类型> q;
int main() {
	执行语句; 
	while(!q.empty()){
		获取位置;
		q.pop();
		if(判断越界)continue;
		for(位置遍历){
			获取新位置; 
			if(跳过条件)continue;
			标记; 
			q.push(新位置);
		}
	}
	return 0;
}

以下以洛谷原题P1443 马的遍历为例:

洛谷题面:

c++代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,sx,sy;
int k[405][405];
int mov[8][2]={{1,2},{-1,2},{1,-2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};//移动数组 
struct hou{//存储位置结构体 
	int a,b;
};
queue<hou>q;//队列 
int main() {
	cin >>n>>m>>sx>>sy;//输入 
	memset(k, -1, sizeof(k));//初始化 
	q.push({sx,sy});//初始位置压入队列 
	k[sx][sy]=0;//初始位置 
	while(!q.empty()){//判空队列 
		int x=q.front().a;
		int y=q.front().b;
		q.pop();//弹出 
		if(x>n||x<1||y>m||y<1)continue;//判断越界 
		for(int i=0;i<8;i++){//遍历移动位置 
			int ux=x+mov[i][0];
			int uy=y+mov[i][1];
			if(k[ux][uy]!=-1||ux>n||ux<1||uy>m||uy<1)continue;//判断非法和已走位置 
			k[ux][uy]=k[x][y]+1;//标记 
			q.push({ux,uy});//压入新位置 
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<k[i][j]<<"	";//输出 
		}
		cout<<endl;
	}
	return 0;
}

推荐题目:

 P1332 血色先锋队

P1746 离开中山路

P1135 奇怪的电梯

总之,DFS和BFS都十分重要,并且可以用来支撑图论和树。

点个赞吧

相关推荐

  1. <span style='color:red;'>DFS</span><span style='color:red;'>与</span><span style='color:red;'>BFS</span>

    DFSBFS

    2024-07-10 21:10:02      17 阅读
  2. 蓝桥杯算法基础(37)BFSDFS

    2024-07-10 21:10:02       23 阅读
  3. 数据结构算法-图论-DFS/BFS

    2024-07-10 21:10:02       24 阅读
  4. 算法 - 回溯 / DFS / BFS

    2024-07-10 21:10:02       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 21:10:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 21:10:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 21:10:02       45 阅读
  4. Python语言-面向对象

    2024-07-10 21:10:02       55 阅读

热门阅读

  1. 每日一题cf

    2024-07-10 21:10:02       19 阅读
  2. Vue3+Element-plus的表单重置

    2024-07-10 21:10:02       16 阅读
  3. #B. 等离子电视

    2024-07-10 21:10:02       22 阅读
  4. 纤程和协程理解

    2024-07-10 21:10:02       18 阅读
  5. 几款常见的数字孪生引擎

    2024-07-10 21:10:02       16 阅读
  6. C++:cv.absdiff函数含义

    2024-07-10 21:10:02       22 阅读
  7. 自动回复机器人:源码搭建与智能化客户服务

    2024-07-10 21:10:02       21 阅读