hdu1242 DFS基础(回溯的重要性)

题目大意:在迷宫里从a出发走到r,每走一格时间+1,但是遇到x时间还要额外+1,求最短的时间。

题解:直接dfs把每一个格子都走一遍,设置一个时间参数,走一格就+1,还要注意回溯和剪枝。

很多新手都会疑惑,回溯有什么用呢?回溯的作用就是在分叉口时你选择了这一条路,往这条路一直走不可回头(用访问数组标记走过的路),走到尽头时,你重新回到那个分叉口(访问数组取消标记),你上一次走的路对于你现在来说是没有走过的,dfs过程中有许多分叉口,所以要用回溯才能走遍每一条路。

具体思路看代码以及注释

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int dir[4][2]={0,1,0,-1,1,0,-1,0};//四个方向 
 5 char a[201][201];
 6 int minn,v[201][201],n,m;
 7 void dfs(int x,int y,int sum)
 8 {
 9     if(a[x][y]=='#')//遇到墙不走 
10     return;
11     if(a[x][y]=='r')//走到了终点 
12     {
13         if(sum<minn)//记录最小值 
14         minn=sum;
15         return;
16     }
17     for(int i=0;i<4;i++)//枚举四个方向 
18     {
19         int xx=x+dir[i][0];
20         int yy=y+dir[i][1];
21         if(a[xx][yy]=='x'&&!v[xx][yy]&&xx>=0&&xx<n&&yy>=0&&yy<m)//将路径限制在n*m之内 
22         {
23             v[xx][yy]=1;//标记要走的路 
24             dfs(xx,yy,sum+2);
25             v[xx][yy]=0;//走遍之后回溯 ,以便下次经过时还能通过 
26         }
27         else if(a[xx][yy]!='x'&&!v[xx][yy]&&xx>=0&&xx<n&&yy>=0&&yy<m)
28         {
29             v[xx][yy]=1;//同上 
30             dfs(xx,yy,sum+1);
31             v[xx][yy]=0;
32         }
33     }
34 }
35 int main()
36 {
37     int sx,sy;
38     while(cin>>n>>m)
39     {
40         for(int i=0;i<n;i++)
41         {
42             for(int j=0;j<m;j++)
43             {
44                 cin>>a[i][j];
45                 if(a[i][j]=='a')
46                 {
47                     sx=i;sy=j;
48                 }
49             }
50         }
51         minn=9999999;
52         memset(v,0,sizeof(v));
53         dfs(sx,sy,0);
54         if(minn==9999999)//如果minn为改变说明没找到 
55         cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
56         else
57         cout<<minn<<endl;
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/spongeb0b/p/9341436.html