UVA 11624 Fire! (bfs)
算法指南白书
分别求一次人和火到达各个点的最短时间
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 7 const int INF = 1000000000; 8 const int maxr = 1000 + 5; 9 const int maxc = 1000 + 5; 10 int R, C; 11 char maze[maxr][maxc]; 12 13 struct Cell { 14 int r, c; 15 Cell(int r, int c):r(r),c(c) {} 16 }; 17 18 const int dr[] = {-1,1,0,0}; 19 const int dc[] = {0,0,-1,1}; 20 int d[maxr][maxc][2], vis[maxr][maxc][2];//0表示人,1表示火走 21 22 queue<Cell> Q; 23 void bfs(int kind) { 24 while(!Q.empty()) { 25 Cell cell = Q.front(); 26 Q.pop(); 27 int r = cell.r, c = cell.c; 28 for(int dir = 0; dir < 4; dir++) { 29 int nr = r + dr[dir], nc = c + dc[dir]; 30 if(nr >= 0 && nr < R && nc >= 0 && nc < C && maze[nr][nc] == '.' && !vis[nr][nc][kind]) { 31 Q.push(Cell(nr, nc)); 32 vis[nr][nc][kind] = 1; 33 d[nr][nc][kind] = d[r][c][kind] + 1; 34 } 35 } 36 } 37 } 38 39 int ans; 40 void check(int r, int c) { 41 if(maze[r][c] != '.' || !vis[r][c][0]) return; // 必须是Joe可达的边界格子 42 if(!vis[r][c][1] || d[r][c][0] < d[r][c][1]) ans = min(ans, d[r][c][0] + 1); // Joe必须先于火到达 43 } 44 45 int main() { 46 int T; 47 scanf("%d", &T); 48 while(T--) { 49 scanf("%d%d", &R, &C); 50 int jr, jc; 51 vector<Cell> fires; 52 for(int i = 0; i < R; i++) { 53 scanf("%s", maze[i]); 54 for(int j = 0; j < C; j++) 55 if(maze[i][j] == 'J') { 56 jr = i; 57 jc = j; 58 maze[i][j] = '.'; 59 } else if(maze[i][j] == 'F') { 60 fires.push_back(Cell(i,j)); 61 maze[i][j] = '.'; 62 } 63 } 64 memset(vis, 0, sizeof(vis)); 65 66 // Joe 67 vis[jr][jc][0] = 1; 68 d[jr][jc][0] = 0; 69 Q.push(Cell(jr, jc)); 70 bfs(0); 71 72 // Fire 73 for(int i = 0; i < fires.size(); i++) { 74 vis[fires[i].r][fires[i].c][1] = 1; 75 d[fires[i].r][fires[i].c][1] = 0; 76 Q.push(fires[i]); 77 } 78 bfs(1); 79 80 // 计算答案 81 ans = INF; 82 for(int i = 0; i < R; i++) { 83 check(i,0); 84 check(i,C-1); 85 } 86 for(int i = 0; i < C; i++) { 87 check(0,i); 88 check(R-1,i); 89 } 90 if(ans == INF) printf("IMPOSSIBLE\n"); 91 else printf("%d\n", ans); 92 } 93 return 0; 94 }