深度优先搜索是图论中的经典算法,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能"深"地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
效率:
作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大。但是,搜索算法毕竟是时间复杂度是O(n!)的阶乘级算法,它的效率比较低,在数据规模变大时,这种算法就显得力不从心了。
正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能"深"地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
效率:
作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大。但是,搜索算法毕竟是时间复杂度是O(n!)的阶乘级算法,它的效率比较低,在数据规模变大时,这种算法就显得力不从心了。
关于深度优先搜索的效率问题,有多种解决方法。最具有通用性的是剪枝(prunning),也就是去除没有用的搜索分支。有可行性剪枝和最优性剪枝两种。
代码:
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int x,y;
int step;
}pr,ne;
int h,w;
int st_x,st_y,endd_x,endd_y;
char mapp[50][50];
int mx[4] = {0,0,1,-1}; //向上下左右四个方向移动;(0,1)(0,-1)(1,0)(-1,0)
int my[4] = {1,-1,0,0};
bool check(int x,int y) //判断是否满足条件的子函数;
{
if (x < 0 || y < 0 || x >= h || y >= w || mapp[x][y] == '#')
return false;
return true;
}
bool dfs(int x,int y)
{
if (x == endd_x && y == endd_y)
return true;
mapp[x][y] = '#';
for (int i = 0 ; i < 4 ; i++)
{
if (check(x+mx[i],y+my[i]))
{
if (dfs(x+mx[i],y+my[i]))
return true;
}
}
return false;
}
int main()
{
scanf ("%d %d",&h,&w);
for (int i = 0 ; i < h ; i++)
{
scanf ("%s",mapp[i]);
for (int j = 0 ; j < w ; j++)
{
if (mapp[i][j] == '@')
{
st_x = i;
st_y = j;
}
else if (mapp[i][j] == '!')
{
endd_x = i;
endd_y = j;
}
}
}
printf ("%s\n",dfs(st_x,st_y) ? "YES" : "NO");
return 0;
}