hdoj1242(dfs 剪枝 解法)
题意:拯救行动,天使r有多个朋友a(friends,在这里被坑了几次,没看清题意),天使被关在牢房里,等着朋友来拯救,求拯救天使的最短距离。
解法:如果不剪枝,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; }
博客原创,转载请说明出处。