POJ 3009 用DFS搜最短路径 适合用来学习DFS

原创 2015年11月18日 17:22:15

说到最短路径,大部分最会想到BFS,DFS求最短路径还是比较少的,我觉得比如只有一种路径可走的话,可以用DFS。

但是这题比较特殊,因为它的规则不像普通迷宫那么简单。具体就不说了。

DFS求最短路径? 那只能是把所有可能到目的地的方法所需步数都比较一下,保存最小的那个值。

所以,搜到一个解之后不能退出DFS,要继续把余下的压在栈里的递归层跑完(当然,跑的时候又会产生新的递归层压入栈),直到所有的情况都遍历了一遍,才能得出最优解。

所以 DFS 函数应该是void型的。

void dfs(int x,int y,int step)
{
    
    ……
   if(……){
  	map[nx][ny]=0;
   	dfs(ex,ey,step+1);
   	map[nx][ny]=1;
   }
   ……
}

如果找到一个解就退出是这样的:

int dfs(---){
        while(---){
            if(找到解) return 1;
            ……
            if(dfs()) return 1;
            ……
        }
        return 0;
     }

由于有step>10就return 以及 越界就不dfs。所以肯定不存在会死循环的问题。

总结:

对于dfs,不要盲目的套形式,dfs只是一个对于某些数据范围小的问题比较有效的工具,它往往和回溯的思想结合再一起,同事具备遍历全图的能力。拿到题目,如果你意识到这可能是一道dfs题,你首先要明白你需要dfs来完成什么工作,从而确定dfs的形式。

对于递归,就是入栈和出栈的过程,i+1层运行完之后,退回到第i当时进入第i+1层的位置,且此时某些变量还是保持第i层的值。直到第一层运行完(即栈空),函数运行结束。

顺便BB一下:我们知道DFS遍历全图的复杂度基本是N*N,还要递归,找出所有可能的方法,DFS的次数肯定比要遍历全图还高的多。而且N达到了20。所以注意到一点,题目规定了,步数大于10可以直接算失败。想想如果没有这个规定不知道怎么做出来。


详细注释代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int map[22][22],m,n,sx,sy;
int dir[][2]={1,0,-1,0,0,1,0,-1};
int ans;
void dfs(int x,int y,int step)
{
    int nx,ny,ex,ey;   //(nx,ny) 代表下一步 (ex,ey) 代表走的这一步
    if(step>10)  return ;  //实际上是剪枝
    for(int i=0;i<4;i++)
    {
        nx=x+dir[i][0];   //下一步
        ny=y+dir[i][1];
        ex=x;
        ey=y;
        while(nx>=0 && nx<m && ny>=0 && ny<n && map[nx][ny]!=1)   //为真代表下一步可走
        {
            ex+=dir[i][0];   //则走这一步
            ey+=dir[i][1];
            if(map[ex][ey]==3) //走的这步是终点吗。
            {
                ans=(step<ans?step:ans);printf("%d\n",step);
                return;
            }
            nx=ex+dir[i][0];  //走完这一步的下一步
            ny=ey+dir[i][1];
            if(nx<0 || nx>=m || ny<0 || ny>=n)
                break;          //如果下一步是越界,说明会直接滑出去,不必再进行dfs
            if(map[nx][ny]==1)  //如果下一步是1,进行深搜.
            {
                map[nx][ny]=0;
                dfs(ex,ey,step+1);
                map[nx][ny]=1;
            }
            //如果下一步还是0,按照题意,当然要继续滑下去,继续while
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m),m||n)
    {
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j]==2)  {sx=i;sy=j;}
            }
        ans=100000;
        dfs(sx,sy,1);
        if(ans==100000)
            printf("-1\n");
        else
            printf("%d\n",ans);
    }

    return 0;
}


版权声明:转载请注明出处 http://blog.csdn.net/angon823

相关文章推荐

HDOJ 5636 Shortest Path(dfs求最短路径)

Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other...

最短路径数 Dijkstra+dfs

寻找最短路径数 标准dijkstra和spfa解法见 《畅通工程续——Dijkstra模板》 本篇多一项要求,求同样cost的最短路径数目。我们用dfs深搜,见代码注释。

Java通过JNI调用C语言的方法

Java以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。 AD: ...

1003. Emergency (25)

题目链接:https://www.patest.cn/contests/pat-a-practise/1003题目大意: 给一个图,求所给两点之间的最短路径的条数,以及这些最短路径中,哪条路径经过的所...

PAT甲级解题报告汇总

PAT甲级解题报告汇总(更新中……)最近在刷PAT甲级题目,AC的题目都发了博文做记录。下面对博文进行一下汇总整理,方便查阅。下面所有题目的解题报告都是本人自己所作,每篇博文都有题目大意的解读,解题思...

BFS和DFS的差别,BFS实现迷宫最短路径

BFS能够求得最短路径,因为BFS每进行一次相当于当前的路径长度。对于一个N*N矩阵,BFS最多运行n*n次。 深度优先搜索相当于一个人在走迷宫,广搜相当于是无穷人沿着不同方向走(因为每条路都同时有...

Manacher算法

网上看到一个很不错的,所以自己就不写了。 链接:https://segmentfault.com/a/1190000003914228 但它的文章有一个小问题:第四幅图蓝线应该是划分在红格的左边。...

POJ 1024 Tester Program(DFS:求单源最短路径)

POJ 1024 Tester Program(DFS求单源最短路径) http://poj.org/problem?id=1024 题意:现在有一个迷宫,我们给出一条最短路径,然后继续给出这个迷宫的...

POJ 1724 ROADS (有限制的最短路径DFS/BFS)

题意:有n座城市,城市之间有道路,道路需要收费,现在Bob想从城市1去城市n,但是他所拥有的钱是有限制的。现在问Bob能否在有限的钱之内到达n城,若能则输出最短路径。 题解:一开始用vector建图...
  • Tsaid
  • Tsaid
  • 2011-10-03 00:40
  • 797

MZY寻宝(深搜dfs写的最短路径)

问题 B: MZY寻宝 时间限制: 1 Sec  内存限制: 128 MB 提交: 165  解决: 50 [提交][状态][讨论版] 题目描述 贪心的MZY去一个迷宫寻宝。已知:若MZ...
  • kflcg
  • kflcg
  • 2015-08-08 17:51
  • 170
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)