DFS
一.深度优先搜索(dfs)
1.什么叫dfs
深度优先搜索类似于树的先序遍历;
是利用栈或者递归的方式实现的,体现出了后进先出的特点;
通俗来说就是一次访问一条路,一直朝着一个方向探索,直到遇到死路退回到前一个分支,继续探索;
一般来说,深度搜索解决的问题主要为寻求所有解和连通性。
2.遍历过程
(1)从图中某个初始顶点v出发,首先访问初始顶点v。
(2)然后依次从v的未被访问的邻接点w,再从w出发进行深度优先遍历,直到图中所有与v有路径相通的的顶点都被访问过为止。
3.算法设计
解决问题:
(1)如何确定一个顶点是否访问过?
设置一个visited[]全局数组,
visited[i]=0表示顶点i没有访问;
visited[i]=1表示顶点i已经访问过。
(在图中也可以修改图本身来实现)
4.dfs算法模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void dfs(int s) { if(找到解了) { 相应的操作; return ; } 尝试每一种可能 { if(满足条件) { 标记走过; 进行下一步dfs; 回溯一步; } } }
|
代码
最短路径(迷宫问题)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include<stdio.h> int r,c,num=10000; char map[41][41]; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; void dfs(int x,int y,int k) { if(x==r&&y==c) { if(num>k) { num=k; } } for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(nx>=1&&nx<=c&&ny>=1&&ny<=r&&map[ny][nx]=='.') { map[ny][nx]='#'; dfs(nx,ny,k+1); map[ny][nx]='.'; } } } int main() { scanf("%d%d",&r,&c); for(int i=1;i<=r;i++) { for(int j=1;j<=c;j++) { scanf(" %c",&map[i][j]); } } map[1][1]='#'; dfs(1,1,1); printf("%d",num); }
|
2. 路径判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include<stdio.h> #include<string.h> int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; int n,ha,la,hb,lb,nx,ny; bool flag; char map[200][200]; void dfs(int x,int y) { for(int i=0;i<4;i++) { nx=x+dx[i]; ny=y+dy[i]; if(nx>=0&&nx<n&&ny>=0&&ny<n&&map[nx][ny]=='.') { map[nx][ny]='#'; if(nx==hb&&ny==lb) { printf("YES\n"); flag=true; break; } else dfs(nx,ny); } } } int main() { int k; scanf("%d",&k); for(int i=0;i<k;i++) { flag=false; scanf("%d",&n); memset(map,'#',sizeof(map)); for(int j=0;j<n;j++) for(int h=0;h<n;h++) { scanf(" %c",&map[j][h]); } scanf("%d%d%d%d",&ha,&la,&hb,&lb); if(map[ha][la]=='#'||map[hb][lb]=='#') { printf("NO\n"); continue; } else { map[ha][la]='#'; dfs(ha,la); } if(!flag) printf("NO\n"); } return 0; }
|