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 }