hdoj1242(dfs 剪枝 解法)

题意:拯救行动,天使r有多个朋友afriends,在这里被坑了几次,没看清题意),天使被关在牢房里,等着朋友来拯救,求拯救天使的最短距离。

解法:如果不剪枝,200*200的地图会超时,可以以天使为起点进行dfs,记录到达map[x][y]的最小值、到达每个a的最小值。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int M = 205;
char map[M][M];
int minL[M][M];   //记录到达x,y的最小值,如果再次到达大于最小值,则说明没有必要走下去了
int minLtoR;
int visited[M][M];
int n,m;
//int step;
int dire[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
void dfs(int v1,int v2,int step)
{
    if(map[v1][v2] == 'a')
    {
        if (step < minLtoR)
        {
            minLtoR = step;  //记录到达a的最小值            
        }
        else return;
    }
    for (int i = 0; i < 4; i++)
    {
        int x = v1+dire[i][0];
        int y = v2+dire[i][1];
        if (!visited[x][y] && map[x][y]!='#' && x < n && x >= 0 && y < m && y >= 0)
        {

            if (step+1 > minL[x][y])
                continue;    //没有必要再走下去了
            else minL[x][y] = step+1; //更新最小值
            visited[x][y] = 1;
            if (map[x][y] == 'x')
                dfs(x,y,step+2);
            else dfs(x,y,step+1);
            visited[x][y] = 0;
        }
    }
}
int main()
{
    while (cin >> n >> m)
    {
        int step = 0;
        minLtoR = 1000000;
        int x,y;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                cin >> map[i][j];
                visited[i][j] = 0;
                minL[i][j] = 1000000;
                if (map[i][j] == 'r')
                {
                    x = i;
                    y = j;
                }
            }
        }
        dfs(x,y,step);
        if (minLtoR == 1000000)
            cout << "Poor ANGEL has to stay in the prison all his life.\n";
        else cout << minLtoR << endl;
    }
    return 0;
}

博客原创,转载请说明出处。

posted @ 2015-08-19 11:58  ediszhao  阅读(642)  评论(0编辑  收藏  举报