FZU 2150 Fire Game(双起点)【BFS】
<题目链接>
题目大意:
两个熊孩子在n*m的平地上放火玩,#表示草,两个熊孩子分别选一个#格子点火,火可以向上向下向左向右在有草的格子蔓延,点火的地方时间为0,蔓延至下一格的时间依次加一。求烧完所有的草需要的最少时间。如不能烧完输出-1。
解题分析:
暴力枚举两个起点,然后用BFS求出这两个火源能够蔓延到最远的草地所花的时间,在那些能够烧完所有草地的情况中,选择用时最少的。
#include <iostream> #include <cstring> #include <queue> #include <cstdio> #include <algorithm> typedef long long ll; const int inf=0x3f3f3f3f; using namespace std; char M[20][20],h[20][20]; int n,m,vis[20][20],res; int next[][2]={-1,0,0,1,1,0,0,-1}; struct node { int x,y,step; }; queue<node>q; vector<node>v; bool judge() //判断是否所有的草全部烧过了 { for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(M[i][j]=='#'&&vis[i][j]==0) return false; return true; } int bfs(node a,node b) { int num; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); q.push(a);vis[a.x][a.y]=1; q.push(b);vis[b.x][b.y]=1; while(!q.empty()) { node now=q.front();q.pop(); num=now.step; node nxt; for(int i=0;i<4;i++){ nxt.x=now.x+next[i][0]; nxt.y=now.y+next[i][1]; nxt.step=now.step+1; if(nxt.x>=0&&nxt.y>=0&&nxt.x<n&&nxt.y<m&&M[nxt.x][nxt.y]=='#'&&!vis[nxt.x][nxt.y]) { vis[nxt.x][nxt.y]=1; q.push(nxt); } } } return num; //num为能够烧到的所有点的最大步数 } int main() { int T,ncase=0;cin>>T; while(T--) { res=inf; scanf("%d %d",&n,&m); getchar(); v.clear(); for(int i=0;i<n;i++){ scanf("%s",M[i]); for(int j=0;j<m;j++){ if(M[i][j]=='#'){ node a;a.x=i,a.y=j,a.step=0; v.push_back(a); } } } for(int i=0;i<v.size();i++){ for(int j=i;j<v.size();j++){ //枚举两个起点 int tmp=min(bfs(v[i],v[j]),res); if(judge())res=min(res,tmp); } } printf("Case %d: ",++ncase); if(res==inf) printf("-1\n"); else printf("%d\n",res); } }
2018-08-29
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。