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

算法之------深度优先搜索DFS和广度优先搜索BFS(最短路径)

广度优先搜索(BFS)(队列实现),用于求解最短路径,一般给出路径最小值,可以被形象的描述为“浅尝辄止”,具体一点就是每个顶点只访问它的邻接节点(如果它的邻接节点没有被访问)并且记录这个邻接节点,当访...
  • nameix
  • nameix
  • 2016年08月24日 20:53
  • 2553

最短路径数 Dijkstra+dfs

寻找最短路径数 标准dijkstra和spfa解法见 《畅通工程续——Dijkstra模板》 本篇多一项要求,求同样cost的最短路径数目。我们用dfs深搜,见代码注释。...
  • abcjennifer
  • abcjennifer
  • 2014年02月18日 15:01
  • 6239

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

Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other...
  • zwj1452267376
  • zwj1452267376
  • 2016年03月06日 22:34
  • 512

迷宫最短路径dfs和bfs代码分析

dfs用递归一步步试探,在所有路径中选出最短的一条路径 代码: //0是路,1是墙 #include #include using namespace std; int x1,y1,x2,y2;//...
  • qq_36238595
  • qq_36238595
  • 2017年02月09日 12:24
  • 506

迷宫问题,求最短路径长度、最短路径条数、所有最短路径,DFS+BFS+栈+队列

迷宫问题,求最短路径长度、最短路径条数、所有最短路径,DFS+BFS+栈+队列
  • Cyibing
  • Cyibing
  • 2013年10月03日 20:17
  • 2224

DFS求起点到终点最短路径,手动输入地图,5行4列,地图如下,起点(1,1)终点(4,3) 1是障碍 0是通路

//DFS求起点到终点最短路径,手动输入地图,5行4列,地图如下,起点(1,1)终点(4,3) 1是障碍 0是通路 //5 4 //0 0 1 0 //0 0 0 0 //0 0 1 0 //0 1 ...
  • guokaigdg
  • guokaigdg
  • 2016年04月02日 17:03
  • 320

BFS、DFS——求最短通路值

题目: 用一个整形矩阵matirx表示一个网络,1代表有路,0代表无路,每一个位置只要不越界,都有上下左右四个方向,求从左上角到右下角的最短通路值。 例如,matrix为:              ...
  • jingsuwen1
  • jingsuwen1
  • 2016年07月23日 20:35
  • 677

ACM-迷宫最短路径(dfs版)

//给定一个大小为N*M的迷宫,迷宫由通道和墙壁组成,每一步可以向邻接 //的上下左右四格的通道移动。请求出从起点到终点的最小部署,本题假设 //从起点一定可以移动到终点 //input // N=1...
  • csx0987
  • csx0987
  • 2015年05月03日 20:16
  • 748

ACM-迷宫最短路径(dfs版)

//给定一个大小为N*M的迷宫,迷宫由通道和墙壁组成,每一步可以向邻接 //的上下左右四格的通道移动。请求出从起点到终点的最小部署,本题假设 //从起点一定可以移动到终点 //input // N=1...
  • csx0987
  • csx0987
  • 2015年05月03日 20:16
  • 748

迷宫最短路径dfs和bfs代码分析

dfs用递归一步步试探,在所有路径中选出最短的一条路径 代码: //0是路,1是墙 #include #include using namespace std; int x1,y1,x2,y2;//...
  • qq_36238595
  • qq_36238595
  • 2017年02月09日 12:24
  • 506
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 3009 用DFS搜最短路径 适合用来学习DFS
举报原因:
原因补充:

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