稍微稍微稍微入门dfs
今天在和同学讨论之后总算是稍微入门了dfs。
明白了几个之前一直没注意或者说是没有明白的问题。
1,dfs执行的顺序应该是第一个递归调用返回后才执行后面一句例如:
dfs(x+1,y);//得他执行完了(得到了返回的结果哪怕是 return ;)才能执行下面的
dfs(x-1,y);
dfs(x,y+1);
dfs(x,y-1);
这种经典的四个方向的深搜就是等第一个dfs执行完,得到返回的结果以后才可以继续执行。也就是说深搜是一个人在搜索
2 注意到无限递归的原因可能不仅仅是没有递归终止,还可能是终止条件模糊。这里放上一个错误的代码:
题目:洛谷P1683入门
#include<bits/stdc++.h>
using namespace std;
char c[25][25];
int w, h;
int r, l;
int ans = 0;
int dx[5] = {0, 1, -1, 0, 0};
int dy[5] = {0, 0, 0, 1, -1};
bool in(int x, int y) {
return (x <= h && x >= 1 && y <= w && y >= 1);
}
void dfs(int x, int y, int t) {
//cout << x << " " << y << endl;
//if(c[x][y] == '.') t++;
if(t > ans) ans = t;
//if(c[x][y] == '#') return ;
int tx, ty;
for(int i = 1; i <= 4; i++) {
tx = x + dx[i];
ty = y + dy[i];
if(in(tx, ty) && c[tx][ty] != '#') {
// cout << tx << " " << ty << endl;
dfs(tx, ty, t+1);
}
}
}
int main() {
cin >> w >> h;
for(int i = 1; i <= h; i++)
for(int j = 1; j <= w; j++){
cin >> c[i][j];
if(c[i][j] == '@') r = i, l = j;
}
// for(int i = 1; i <= h; i++){
// for(int j = 1; j <= w; j++)
// cout << c[i][j];
// cout <<endl;
//
// }
// cout <<r <<l <<endl;
dfs(r, l, 1);
cout << ans << endl;
return 0;
}
先不说题目的意思和,自己的做法,就看这个代码为什么会无限递归。
在题目的图中:
在标注的区域内可能左右不停的移动搜索,那么自然无限递归了
所以,在这里,或者说大部分的题目当中一定要慎重考虑是不是要标记已经搜索过的点
3,关于回溯的问题:
像这道题目自然是不用回溯的,因为无论通过哪条路径走到这块瓷砖上面,都只能计算一次。
但是有些题目,比如:寻找一个点到另一个点的最短路径这种,那么,这个点必须要可以被其他的路径走过,因为只有这样,才可以找到最短的路径。要不然,因为你这个点被搜过了,然后其他的路径就没办法通过这个点了,那肯定是找不到最短路径的!!!