DFS剪枝處理HDU1010

http://acm.hdu.edu.cn/showproblem.php?pid=1010

題意很好理解,不是最短路,而是dfs,雖然地圖不算大,稍微注意一點的dfs也能險過,可是700+ms和78ms一對比仍是讓人難受php

對dfs的剪枝處理,實際上就是一個邏輯推理ios

面對整個地圖我能夠作出如下判斷若是 n * m - wall <= t那就必定say NO優化

n * m 是整個地圖的大小,wall是地圖中牆的個數相減以後就是最多能夠走的步數,之因此取到等號是由於在第0秒的時候,已經走了一個地方了(起點)spa

這就是路徑剪枝
接下來看一看奇偶剪枝:code

奇偶剪枝:
把矩陣標記成以下形式
0,1,0,1,0
1,0,1,0,1
0,1,0,1,0
1,0,1,0,1blog

起點和終點奇偶不一樣——要走奇數步,奇偶相同——要走偶數步,與路徑剪紙不一樣的是奇偶剪紙能夠放到dfs裏,對dfs的優化效果也很好get

進而能夠推出下面的關係(他們之間的關係有一個就是奇數-奇數=偶數,偶數-偶數=偶數,因此若是temp是奇數,那麼就say no)string

  令 temp = (t - step) - (abs(sx - ex) + abs(sy - ey));
    abs(sx - ex) + abs(sy - ey)到達終點最少還要的步數
    t - step 還剩下的步數
    1——》temp < 0 確定到不了了return
    2——》temp > 0 
    (1)temp是奇數 --》繞道多走必然多走偶數步-出去一步,進來以不,
    //例如走a b你能夠試一試不管怎麼走再回到正軌上確定多走偶數步因此retur
    (2)temp是偶數--》能夠正常dfs
  it

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
using namespace std;
const int maxn = 10;
int mp[10][10];
int vis[10][10];
int foot[4][2] = {1,0,-1,0,0,1,0,-1};
int n,m,t,sx,sy,ex,ey,wall;
int retflag;
void init()
{
    memset(mp,0,sizeof(mp));
    memset(vis,0,sizeof(vis));
    retflag = 0;
    wall = 0;
}
void dfs(int x,int y,int step)
{
    if(x == ex && y == ey)
    {
        if(step == t)
        {
            retflag = 1;
        }
        return;
    }
    if(retflag)return;
    int temp = (t - step) - (abs(sx - ex) + abs(sy - ey));
    if(temp < 0 || temp & 1)
    {
        return;
    }
    for(int i = 0;i < 4;i++)
    {
        int nx = x + foot[i][0];
        int ny = y + foot[i][1];
        if(nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && mp[nx][ny] != 1)
        {
            vis[nx][ny] = 1;
            dfs(nx,ny,step + 1);
            vis[nx][ny] = 0;
        }
    }
}

int main()
{
    char ch;
    while(~scanf("%d%d%d",&n,&m,&t))
    {
        getchar();
        if(!n && !m && !t)break;
        init();
        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j < m;j++)
            {
                scanf("%c",&ch);
                if(ch=='X'){mp[i][j] = 1;wall++;}
                if(ch=='S')
                {
                    sx = i;
                    sy = j;
                    vis[i][j] = 1;
                }
                if(ch=='D')
                {
                    ex = i;
                    ey = j;
                }
                if(ch=='.')mp[i][j] = 0;
            }
            getchar();
        }
        if(n * m - wall <= t)
        {
            printf("NO\n");
            continue;
        }
        dfs(sx,sy,0);
        if(retflag)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
相關文章
相關標籤/搜索