深度优先搜索dfp学习
>>定义
深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.(according to Baidu)
>>几个例子
eg1
http://ybt.ssoier.cn:8088/problem_show.php?pid=1215
#include<bits/stdc++.h> using namespace std; int k,h; char c[105][105]; bool ans=false; int x[4]={1,0,-1,0}; int y[4]={0,-1,0,1}; int ax,ay,bx,by,nx,ny; bool b[1005][1005]; void dfp(int x1,int y1){ if(ans){ return ; } for(int i=0; i<=3; i++){ nx=x[i]+x1; ny=y[i]+y1; if(c[nx][ny]=='.' && nx>=0 && nx<h && ny>=0 && ny<h && b[nx][ny]==false){ if(nx==bx && ny==by){ ans=true; } b[nx][ny]=true; dfp(nx,ny); b[nx][ny]=false; } } } int main(){ cin>>k; for(int i=0; i<k; i++){ cin>>h; for(int j=0; j<h; j++){ for(int z=0; z<h; z++){ cin>>c[j][z]; } } cin>>ax>>ay>>bx>>by; dfp(ax,ay); if(ans==false){ cout<<"NO"<<endl; }else cout<<"YES"<<endl; ans=false; memset(b,0,sizeof(b));//要记得清空!!! } return 0; }
eg2
1212LETTERS(求最长路径)
http://ybt.ssoier.cn:8088/problem_show.php?pid=1212
#include<bits/stdc++.h> using namespace std; int maxs=0; bool a[25][25],b[10005]; char c[25][25]; int R,S; int x[4]={1,0,-1,0}; int y[4]={0,1,0,-1}; void dfs(int m,int n,int s){ if(s>maxs){ maxs=s; } for(int i=0; i<=3; i++){ int nx=x[i]+m; int ny=y[i]+n; if(nx<=R && ny<=S && nx>=1 && ny>=1){ if(b[c[nx][ny]]==false && a[nx][ny]==false){ b[c[nx][ny]]=true; a[nx][ny]=true; dfs(nx,ny,s+1); b[c[nx][ny]]=false; a[nx][ny]=false; } } } } int main(){ cin>>R>>S; for(int i=1; i<=R; i++){ for(int j=1; j<=S; j++){ cin>>c[i][j]; } } b[c[1][1]]=1; dfs(1,1,1); cout<<maxs<<endl; return 0; }
eg3
1213八皇后问题
http://ybt.ssoier.cn:8088/problem_show.php?pid=1213
#include<bits/stdc++.h> using namespace std; int a[10][10],s=0; bool b[1000], c[1000],d[1000]; void output(){ cout<<"No. "<<s<<endl;//注意好是大写还是小写 for(int i=1; i<=8; i++){ for(int j=1; j<=8; j++){ cout<<a[j][i]<<" "; } cout<<endl; } } void dfs(int m){ for(int j=1; j<=8; j++){ if(b[j]==false && c[m+j-1]==false && d[m-j+8]==false){ a[m][j]=1; b[j]=true; c[m+j-1]=true; d[m-j+8]=true; if(m==8){ s++; output(); }else { dfs(m+1); } b[j]=false; c[m+j-1]=false; d[m-j+8]=false; a[m][j]=0;//"=="和"="不要搞错啦!!! } } } int main(){ dfs(1); return 0; }
>>Conclusion:1.不能走重复的路(用bool型判断+标记)(记得还原)
2.上下左右走可以用int x,y的数组来达成
3.每一次完成做需要做的标记(如比大小,统计次数等等)
int x[4]={1,0,-1,0}; int y[4]={0,1,0,-1}; void dfs(int m,int n){//坐标(+方案数……) if(达成需要的目标/比大小){ 做标记/赋值 } for(int i=0; i<=3; i++){ int nx=x[i]+m; int ny=y[i]+n;//以上下左右为例,表示走的方向 if(nx<=R && ny<=S && nx>=1 && ny>=1)//保证不走出去 { if(b[c[nx][ny]]==false && a[nx][ny]==false)//确保这条路未走过(不回头) { b[c[nx][ny]]=true; a[nx][ny]=true; //表示此条路已走过 dfs(nx,ny);// b[c[nx][ny]]=false; a[nx][ny]=false;//将路径还原 } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律