深度优先算法总结及运用
什么是深度优先搜索(DFS)?
深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为DFS即Depth First Search。
深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。
其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
深度优先的基本原则:按照某种条件往前试探搜索,如果前进中遭到失败(正如老鼠遇到死胡同)则退回头另选通路继续搜索,直到找到满足条件的目标为止。
下面是关于深度优先搜索的图示:
算法描述:
可以看出,我们必须知道顶点是否已经被访问过。
所以在具体实现时,我们可以用一个全局数组visited来记录顶点是否被访问过。
如果visited[i]的值为True,则顶点vi已经被访问过,否则没有被访问。
DFS背后的想法是尽可能深入到图形中,并在没有任何未访问的相邻顶点的情况下回溯到顶点。
递归地描述/实现算法非常容易:我们在一个顶点开始搜索。
在访问顶点之后,我们进一步对我们之前没有访问过的每个相邻顶点执行DFS。
这样我们就可以访问从起始顶点可到达的所有顶点。
算法实现:
int n; vector<bool> visited; void dfs(int v) { visited[v] = true; for () { if (!visited[u]) dfs(u); } }
DFS的运用:
走迷宫:
给一个n行m列的2维的迷宫,'S'表示迷宫的起点,'T'表示迷宫的终点,'#'表示不能通过的点,'.' 表示可以通过的点。 你需要从'S'出发走到'T',每次只能上下左右走动,并且只能进入能通过的点,每个点只能通过一次。现在要求你求出有多少种通过迷宫的的方案。
输入格式
第一行输入n,m(1≤n,m≤10)表示迷宫大小。接下来输入n 行字符串表示迷宫。
输出格式
输出通过迷宫的方法数。
样例输入
2 3
S.#
..T
样例输出
2
代码实现
1 #include <iostream> 2 #include<cmath> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include <algorithm> 7 using namespace std; 8 typedef long long ll; 9 10 //调用Enter函数和DFS函数 11 void Enter(); 12 void DFS(int i,int j); 13 int n,m,x,y,way;//n,m记录迷宫大小,x,y记录'S'的地址, way记录路径的数量 14 char Maze[10][10];//存储迷宫 15 int Flag[10][10];//在DFS函数中标记 0为没经过,1为已经经过 16 17 18 int main() 19 { 20 int i,j; 21 cin>>n>>m; 22 for(i=0;i<n;i++) 23 { 24 for(j=0;j<m;j++) 25 { 26 cin>>Maze[i][j]; 27 } 28 } 29 Enter();//查找入口'S'位置,记录其坐标x,y位置 30 DFS(x,y);//用深度优先搜索函数统计其路径 31 cout<<way<<endl; 32 33 return 0; 34 } 35 36 void Enter() 37 { 38 for(int i=0;i<n;i++) 39 { 40 for(int j=0;j<m;j++) 41 { 42 if(Maze[i][j]='S') 43 { 44 x=i; 45 y=j; 46 return; 47 } 48 } 49 } 50 } 51 52 void DFS(int i,int j) 53 { 54 if(i<0||j<0||i>=n||j>=m) 55 { 56 return; 57 } 58 if(Maze[i][j]=='T') 59 { 60 way++; 61 return; 62 } 63 else if(Maze[i][j]=='#') 64 { 65 return; 66 } 67 else 68 { 69 if((Maze[i][j]=='.'||Maze[i][j]=='S')&&Flag[i][j]==0) 70 { 71 Flag[i][j]=1; 72 //迭代的过程 73 DFS(i,j+1);//向上遍历 74 DFS(i+1,j);//向右遍历 75 DFS(i,j-1);//向下遍历 76 DFS(i-1,+j);//向左遍历 77 78 Flag[i][j]=0; 79 } 80 } 81 }