1. 程式人生 > 實用技巧 >Fire Game FZU - 2150(雙起點BFS)

Fire Game FZU - 2150(雙起點BFS)

Fire Game

放火燒山

法外狂徒張三在n*m的平地上放火玩,#表示草,張三有分身,他的分身和他本人分別選一個#格子點火,火可以向上向下向左向右在有草的格子蔓延,點火的地方時間為0,蔓延至下一格的時間依次加一。求燒完所有的草需要的最少時間。如不能燒完輸出-1。

Input

第一行,輸入一個T,表示有T組測試資料。
每組資料由一個n,m分別表示行列

1 <= T <=100, 1 <= n <=10, 1 <= m <=10

Output

輸出最少需要的時間>

Sample Input

4
3 3
.#.
###
.#.
3 3
.#.
#.#
.#.
3 3
...
#.#
...
3 3
###
..#
#.#

Sample Output

Case 1: 1
Case 2: -1
Case 3: 0
Case 4: 2

思路:
將自己和分身作為起點同時放入佇列向四周的合法區域搜尋,定義剩下的草堆數量lleft,當lleft=0是說明草堆燒完找到一種情況,否則返回-1表示無法燒完草堆。
注意點:
1.需要遍歷雙起點座標的所有組合尋找最小的情況。
2.當只有一個 . 或者 # 時直接輸出0。

程式碼:
  1 #include <set>
  2 //#include <map>
  3 #include <list>
  4 #include <stack>
  5 #include <queue>
  6
#include <deque> 7 #include <cmath> 8 #include <string> 9 #include <vector> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <sstream> 14 #include <iostream> 15 #include <algorithm> 16 //#include <unordered_map>
17 #define INF 0x3f3f3f3f 18 #define ll long long 19 #define ull unsigned long long 20 #define FILL(a,n,v) fill(a,a+n,v) 21 #define Mset(a,v) memset(a,v,sizeof a) 22 #define fcio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) 23 using namespace std; 24 const int maxn=20; 25 int n,m; 26 string map[maxn]; 27 int dir[5][2]={{1,0},{0,1},{-1,0},{0,-1}}; 28 29 struct node 30 { 31 int x,y; 32 int step; 33 //int left; 34 node(int x1,int y1) 35 { 36 this->x=x1; 37 //this->x2=x2; 38 this->y=y1; 39 //this->y2=y2; 40 this->step=0; 41 } 42 }; 43 bool vis[maxn][maxn]; 44 bool check(int x1,int y1) 45 { 46 if(!((x1>=0)&&(x1<n)&&(y1>=0)&&(y1<m))) return false; 47 if(map[x1][y1]!='#') return false; 48 if(!vis[x1][y1]) return false; 49 return true; 50 } 51 52 int gleft; 53 int bfs(int x1,int y1,int x2,int y2) 54 { 55 Mset(vis,true); 56 vis[x1][y1]=false; 57 vis[x2][y2]=false; 58 node now(x1,y1); 59 //now.left=gleft-2; 60 queue<node>q; 61 q.push(now); 62 node now1(x2,y2); 63 q.push(now1); 64 int lleft=gleft-2; 65 if(lleft<=0) return 0; 66 while(!q.empty()) 67 { 68 now=q.front(); 69 //if(lleft==0) return now.step; 70 q.pop(); 71 for(int i=0;i<4;i++) 72 { 73 int nx=now.x+dir[i][0]; 74 int ny=now.y+dir[i][1]; 75 if(check(nx,ny)) 76 { 77 vis[nx][ny]=false; 78 node next(nx,ny); 79 next.step=now.step+1; 80 lleft--; 81 if(lleft==0) return next.step; 82 q.push(next); 83 } 84 } 85 } 86 return -1; 87 } 88 89 int main() 90 { 91 int t; 92 cin>>t; 93 for(int ca=1;ca<=t;ca++) 94 { 95 cin>>n>>m; 96 for(int i=0;i<n;i++) cin>>map[i]; 97 gleft=0; 98 for(int i=0;i<n;i++) 99 { 100 for(int j=0;j<m;j++) 101 { 102 if(map[i][j]=='#') gleft++; 103 } 104 } 105 if(!gleft) 106 { 107 cout<<"Case "<<ca<<": "<<0<<endl; 108 continue; 109 } 110 int res=INF; 111 for(int i=0;i<n;i++) 112 { 113 for(int j=0;j<m;j++) 114 { 115 if(map[i][j]=='#') 116 { 117 for(int j1=j;j1<m;j1++) 118 { 119 if(map[i][j1]=='#') 120 { 121 int b=bfs(i,j,i,j1); 122 if(b>=0) res=min(res,b); 123 } 124 } 125 for(int i1=i+1;i1<n;i1++) 126 { 127 for(int j1=0;j1<m;j1++) 128 { 129 if(map[i1][j1]=='#') 130 { 131 int b=bfs(i,j,i1,j1); 132 if(b>=0) res=min(res,b); 133 } 134 } 135 } 136 } 137 } 138 } 139 cout<<"Case "<<ca<<": "; 140 if(res==INF) cout<<-1<<endl; 141 else cout<<res<<endl; 142 143 } 144 }