題目連接:http://acm.fzu.edu.cn/problem.php?pid=2150php
題目大意:小明小紅要在一塊網格狀土地上玩火。土地上有的地方是草塊,有的地方是空地。草地會被相鄰格子的火引燃,土地不會。小明小紅想要讓全部有草的格子都燃燒,而且它倆各自點着了一塊草地(可能同樣)。問是否可以達到他們的目的?若是能,最少須要多長時間才能燒徹底部的草地。node
解題思路:顯然有三個以上互相不連通的草地塊那麼就沒法達到目的了,若是有兩個,那必須一人點一個草地塊,若是有一個就職選兩個格子點燃,即:this
DFS求連通塊個數,若兩個-對於每一個塊,枚舉每一個點,BFS求最少時間而後求兩個最小時間的最大值;若一個-枚舉這個快內任意兩個點(能夠同樣),而後兩個點同時爲起點bfs便可,最後求最小值便可。spa
代碼:code
1 const int inf = 0x3f3f3f3f; 2 const int iadd[] = {0, 1, 0, -1}, jadd[] = {1, 0, -1, 0}; 3 const int maxn = 15; 4 char maze[maxn][maxn]; 5 int n, m; 6 int bt[maxn][maxn], cnt = 0; 7 int anss[3]; 8 short vis[maxn][maxn]; 9 10 void dfs(int x, int y){ 11 vis[x][y] = 1; bt[x][y] = cnt + 1; 12 for(int i = 0; i < 4; i++){ 13 int vi = x, vj = y; 14 vi += iadd[i]; vj += jadd[i]; 15 if(vi < 0 || vj < 0 || vi >= n || vj >= m) continue; 16 if(maze[vi][vj] == '.' || vis[vi][vj]) continue; 17 dfs(vi, vj); 18 } 19 } 20 21 struct node{ 22 int i, j, t; 23 }; 24 int bfs(int i, int j){ 25 queue<node> q; 26 memset(vis, 0, sizeof(vis)); 27 vis[i][j] = 1; 28 node u; u.i = i; u.j = j; u.t = 0; 29 q.push(u); 30 int ans = 0; 31 while(!q.empty()){ 32 u = q.front(); q.pop(); 33 ans = u.t; u.t++; 34 for(int i = 0; i < 4; i++){ 35 node v = u; 36 v.i += iadd[i]; v.j += jadd[i]; 37 if(v.i < 0 || v.j < 0 || v.i >= n || v.j >= m) continue; 38 if(maze[v.i][v.j] == '.' || vis[v.i][v.j]) continue; 39 vis[v.i][v.j] = 1; 40 q.push(v); 41 } 42 } 43 anss[bt[i][j]] = min(anss[bt[i][j]], ans); 44 } 45 46 int bfs(int i1, int j1, int i2, int j2){ 47 memset(vis, 0, sizeof(vis)); 48 queue<node> q; 49 vis[i1][j1] = vis[i2][j2] = 1; 50 node u1; u1.i = i1; u1.j = j1; u1.t = 0; 51 node u2; u2.i = i2; u2.j = j2; u2.t = 0; 52 q.push(u1); q.push(u2); 53 int ans = 0; 54 while(!q.empty()){ 55 node u = q.front(); q.pop(); 56 ans = max(ans, u.t); 57 u.t++; 58 for(int i = 0; i < 4; i++){ 59 node v = u; 60 v.i += iadd[i]; v.j += jadd[i]; 61 if(v.i < 0 || v.j < 0 || v.i >= n || v.j >= m) continue; 62 if(maze[v.i][v.j] == '.' || vis[v.i][v.j]) continue; 63 q.push(v); 64 vis[v.i][v.j] = 1; 65 } 66 } 67 return ans; 68 } 69 70 int main(){ 71 int T; 72 scanf("%d", &T); 73 for(int t = 1; t <= T; t++){ 74 memset(bt, 0, sizeof(bt)); 75 cnt = 0; 76 scanf("%d %d", &n, &m); 77 for(int i = 0; i < n; i++){ 78 scanf("%s", maze[i]); 79 } 80 printf("Case %d: ", t); 81 memset(vis, 0, sizeof(vis)); 82 for(int i = 0; i < n; i++){ 83 for(int j = 0; j < m; j++){ 84 if(maze[i][j] == '#' && !vis[i][j]){ 85 dfs(i, j); 86 cnt++; 87 } 88 } 89 } 90 if(cnt == 0) { 91 puts("0"); 92 continue; 93 } 94 else if(cnt >= 3){ 95 puts("-1"); 96 continue; 97 } 98 else if(cnt == 1){ 99 vector<PII> va; 100 for(int i = 0; i < n; i++) 101 for(int j = 0; j < m; j++) 102 if(maze[i][j] == '#') 103 va.push_back(PII(i, j)); 104 int ans = inf; 105 for(int i = 0; i < va.size(); i++){ 106 for(int j = i; j < va.size(); j++){ 107 int tmp = bfs(va[i].first, va[i].second, va[j].first, va[j].second); 108 ans = min(tmp, ans); 109 } 110 } 111 printf("%d\n", ans); 112 continue; 113 } 114 memset(vis, 0, sizeof(vis)); 115 memset(anss, 0x3f, sizeof(anss)); 116 for(int i = 0; i < n; i++){ 117 for(int j = 0; j < m; j++){ 118 if(maze[i][j] == '#') bfs(i, j); 119 } 120 } 121 if(anss[1] >= inf) anss[1] = -1; 122 if(anss[2] >= inf) anss[2] = -1; 123 printf("%d\n", max(anss[2], anss[1])); 124 } 125 }
題目:blog
Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty and then they start to fire all the grass. Firstly they choose two grids which are consisting of grass and set fire. As we all know, the fire can spread among the grass. If the grid (x, y) is firing at time t, the grid which is adjacent to this grid will fire at time t+1 which refers to the grid (x+1, y), (x-1, y), (x, y+1), (x, y-1). This process ends when no new grid get fire. If then all the grid which are consisting of grass is get fired, Fat brother and Maze will stand in the middle of the grid and playing a MORE special (hentai) game. (Maybe it’s the OOXX game which decrypted in the last problem, who knows.)ip
You can assume that the grass in the board would never burn out and the empty grid would never get fire.ci
Note that the two grids they choose can be the same.get
The first line of the date is an integer T, which is the number of the text cases.input
Then T cases follow, each case contains two integers N and M indicate the size of the board. Then goes N line, each line with M character shows the board. 「#」 Indicates the grass. You can assume that there is at least one grid which is consisting of grass in the board.
1 <= T <=100, 1 <= n <=10, 1 <= m <=10
For each case, output the case number first, if they can play the MORE special (hentai) game (fire all the grass), output the minimal time they need to wait after they set fire, otherwise just output -1. See the sample input and output for more details.