HDOJ-1010(DFS + 奇偶剪枝)

刚开始忘了判断是否在过程中路过终点(这也是要剪枝的,因为所有点只能访问一次),各种TLE,然后试图加路径记录用map存储,结果各种MLE,也不知道怎么的,突然想起来终点必须要最后访问,加上这条判断就A了:

#include 
#include 
#include 
using namespace std;

const int MOVE[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int N, M, T;
char maze[6][6];
int sr, sc, dr, dc;

bool input()
{
	scanf("%d %d %d", &N, &M, &T);
	if(!N) return false;
	
	for(int i = 0; i < N; ++i){
		while(getchar() != '\n') ;
		for(int j = 0; j < M; ++j){
			maze[i][j] = getchar();
			if(maze[i][j] == 'S'){
				sr = i;
				sc = j;
			}
			else if(maze[i][j] == 'D'){
				dr = i;
				dc = j;
			}
		}
	}
	return true;
}
inline bool isReachable(int r, int c){
    return !(r < 0 || r >= N || c < 0 || c >= M || maze[r][c] == 'X');
}
bool search(int r, int c, int t)
{
    bool flag = false;
    if(t == 0) flag = maze[r][c] == 'D';
    else if(maze[r][c] != 'D'){//过程中不能访问终点
        int dis = abs(r - dr) + abs(c - dc);
        if(dis <= t && !((t - dis) & 1)){//汉密尔顿距离 + 奇偶性剪枝
        //try to move forward
            --t;
            char save = maze[r][c];
            maze[r][c] = 'X';
            for(int i = 0; i < 4; ++i){
                int nr = r + MOVE[i][0], nc = c + MOVE[i][1];
                if(isReachable(nr, nc) && search(nr, nc, t)){
                    flag = true;
                    break;
                }
            }
        //recover situation
            maze[r][c] = save;
            ++t;
        }
    }
    return flag;
}

int main()
{
    while(input()){
        if(search(sr, sc, T)) puts("YES");
        else puts("NO");
    }
    return 0;
}


你可能感兴趣的:(DFS,每天A一道题)