hdu - 1072(dfs剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072

思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2;如果之前走过的时间小于这一次,

就说明有更短的;路径,所以就不用继续遍历下去。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[20][20],step[20][20],tim[20][20],m,n,ans;
int zz[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
void dfs(int x,int y,int s1,int s2)
{
    //cout<<"a=="<<x<<" "<<y<<" "<<a[x][y]<<endl;
    if(s1<=0||s2>=64) return ;
    if(x<=0||x>n||y<=0||y>m) return ;
    if(a[x][y]==0) return ;
    if(a[x][y]==3)
    {
        ans=min(ans,s2);
        return ;
    }
    if(a[x][y]==4)
    {
        s1=6;
    }
    if(step[x][y]<=s2&&tim[x][y]>=s1) return ;
    step[x][y]=s2;
    tim[x][y]=s1;
    for(int i=0;i<4;i++)
    {
        int tx=x+zz[i][0],ty=y+zz[i][1];
        dfs(tx,ty,s1-1,s2+1);
    }
}
int main(void)
{
    int i,j,t,sx,sy;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        scanf("%d %d",&n,&m);
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++) 
            {
                tim[i][j]=0;
                step[i][j]=64;
                scanf("%d",&a[i][j]);
                if(a[i][j]==2) sx=i,sy=j;
            }
        ans=64;
        dfs(sx,sy,6,0);
        if(ans==64)
        printf("-1\n");
        else
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/2018zxy/p/9757912.html