当前位置: 首页 > news >正文

DFS和BFS的模版

dfs

dfs金典例题理解就是走迷宫

P1605 迷宫 - 洛谷

image-20250408213319450

dfs本质上在套一个模版:

image-20250408213947949

image-20250408213958733

///dfs
#include<bits/stdc++.h>
using namespace std;
int a[10][10]={0};
int m,n,t,ans=0;
int ex,ey;
int v[10][10]={0};
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y){
	if(x==ex&&y==ey){
		ans++;
		return;
	}
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
//		判断是否越界
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&v[nx][ny]==0&&a[nx][ny]==0){
			v[nx][ny]=1;
			dfs(nx,ny);
			v[nx][ny]=0;
		}
	}
}
int main(){
	int x,y,t,t1,t2;
	cin>>n>>m>>t;
	cin>>x>>y>>ex>>ey;
	for(int i=0;i<t;i++){
		cin>>t1>>t2;
		a[t1][t2]=1;
	}
	if(x==ex&&y==ey){
		cout<<ans;
		return 0;
	}
	v[x][y]=1;
	dfs(x,y);
	cout<<ans;
	return 0;
}

P1238 走迷宫 - 洛谷

image-20250408214154504

//走迷宫
#include<bits/stdc++.h>
using namespace std;
int m,n;
int ex,ey,bg,ed;
int a[20][20]={0},v[20][20]={0};
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
bool flag=false;
vector<int>px;
vector<int>py;
void dfs(int x,int y){
	if(x==ex&&y==ey){
		flag=true;
		cout<<"("<<bg<<","<<ed<<")";
		for(int i=0;i<px.size();i++){
			cout<<"->("<<px[i]<<","<<py[i]<<")";
		}
		cout<<endl;
		return;
	}
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=1&&ny>=1&&nx<=m&&ny<=n&&a[nx][ny]==1&&v[nx][ny]==0){
			v[nx][ny]=1;
			px.push_back(nx);
			py.push_back(ny);
			dfs(nx,ny);
			px.pop_back();
			py.pop_back();
			v[nx][ny]=0;
		}
	}
	
	
}
int main(){
	cin>>m>>n;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	int x,y;
	cin>>x>>y>>ex>>ey;
	bg=x;ed=y;
	v[x][y]=1;
	dfs(x,y);
	if(!flag)
		cout<<"-1";
	return 0;
}

套模版解决迷宫问题,good

dfs和bfs的主要区别和应用场景

image-20250408221743063

dfs适合去求有没有路径,使用类似大水冲灌的思想,bfs地毯式搜索

bfs

bfs模版如下:

void bfs()
{
	 初始化,初始状态存数组; 
	 int head=0,tail=1,que[max_size];//构建队列
	 标记初始点 
	 while(head<tail)
	 {
	 	head++;//指向待扩展结点
		for(i=1;i<=maxi;++i)
		{
			if(满足条件||不重复)
			{
				tail++;
				将新节点存入队列
			}	
		}
	}
}

P1443 马的遍历 - 洛谷

image-20250408222813997

//马走日
#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans[500][500]={0};
int v[500][500]={0};
struct Queue{
	int x;
	int y;
}que[500110];
int dx[8]={-1,-2,-1,-2,1,2,2,1};
int dy[8]={-2,-1,2,1,-2,-1,1,2};
void bfs(int x,int y){
	int head=0,tail=1;
	int sum=0;
	while(head<tail){
		head++;
		sum=ans[que[head].x][que[head].y]+1;
		for(int i=0;i<8;i++){
			int nx=que[head].x+dx[i];
			int ny=que[head].y+dy[i];
			if(nx>=1&&ny>=1&&nx<=n&&ny<=m&&v[nx][ny]==0){
				v[nx][ny]=1;
				tail++;
				que[tail].x=nx;
				que[tail].y=ny;
				ans[nx][ny]=sum;
			}
		}	
	}

	
	
}
int main(){
	int x,y;
	cin>>n>>m>>x>>y;
	v[x][y]=1;
	que[1].x=x;
	que[1].y=y;
	bfs(x,y);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(ans[i][j]==0&&(i!=x||j!=y))
				cout<<left<<setw(5)<<"-1";
			else
				cout<<left<<setw(5)<<ans[i][j];
		}
		cout<<endl;
	}
	return 0;
}

陷阱:第一默认0为-1,排除的不是(1,1)而是(x,y)

第二更正好n,m,要知道什么行和列

相关文章:

  • Linux 基础入门操作 前言 VIM的基本操作 2
  • Java logback框架日志输出中文乱码的解决方案(windows)
  • 【Easylive】定时任务-每日数据统计和临时文件清理
  • JavaWeb 课堂笔记 —— 04 Ajax
  • 我提了一个 Androidx IssueTracker
  • [QMT量化交易小白入门]-四十二、五年年化收益率26%,当日未成交的下单,取消后重新委托
  • PHP开发效率提升利器:通义灵码在VSCode中的应用与技巧
  • Model Context Protocol(MCP)介绍
  • CPP杂项
  • 下载firefox.tar.xz后如何将其加入到Gnome启动器
  • 《Spring Boot+策略模式:企业级度假订单Excel导入系统的架构演进与技术实现》
  • vue3的一些新特性
  • vcs中的looprepprt
  • kafka存储原理
  • 定积分__
  • C应用常见的编程错误
  • java入门
  • LeetCode:有效的括号
  • mysql镜像创建docker容器,及其可能遇到的问题
  • 远程监控系统项目里练习
  • 重温经典|开播20周年,仙剑的那些幕后你知道吗?
  • 游客称在网红雪山勒多曼因峰需救援被开价2.8万,康定文旅:封闭整改
  • 首批证券公司科创债来了!拟发行规模超160亿元
  • 上海发布预付卡消费“10点提示”:警惕“甩锅闭店”套路
  • 第1现场 | 印巴冲突:印50多年来首次举行大规模民防演习
  • A股低开高走全线上涨:军工股再度领涨,两市成交12934亿元