FZU 2150 Fire Game (兩點BFS)
阿新 • • 發佈:2018-12-09
題意:兩個熊孩子在n*m的平地上放火玩,#表示草,兩個熊孩子分別選一個#格子點火,火可以向上向下向左向右在有草的格子蔓延,點火的地方時間為0,蔓延至下一格的時間依次加一。求燒完所有的草需要的最少時間。如不能燒完輸出-1。
思路:第一感覺是DFS求連通塊,但想想就感覺不對了。要求最少時間,還是BFS,先列舉兩個點,如果是#就把這兩個點入佇列,然後擴充套件,每一次bfs的最後要找出燃燒時間最長的點的時間,再在每一次列舉後取最小值。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int maxn=200005; const double eps=1e-8; const double PI = acos(-1.0); struct node { int x,y; node(int x,int y):x(x),y(y) {} node() {} }; char g[15][15]; node s1,s2; int dx[]={-1,1,0,0}; int dy[]={0,0,-1,1}; int vis[15][15],step[15][15]; int n,m; int bfs() { queue<node> q; q.push(s1); q.push(s2); memset(vis,0,sizeof(vis)); memset(step,inf,sizeof(step)); step[s1.x][s1.y]=0; step[s2.x][s2.y]=0; vis[s1.x][s1.y]=1; vis[s2.x][s2.y]=1; while(!q.empty()) { node f=q.front(); q.pop(); for(int i=0;i<4;i++) { int x=f.x+dx[i]; int y=f.y+dy[i]; if(x>=0&&x<n&&y>=0&&y<m&&!vis[x][y]&&g[x][y]=='#') { q.push(node(x,y)); step[x][y]=step[f.x][f.y]+1; vis[x][y]=1; } } } int maxx=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(g[i][j]=='#') { maxx=max(maxx,step[i][j]); } } } return maxx; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int t,cas=0; cin>>t; while(t--) { cin>>n>>m; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { cin>>g[i][j]; } } int ans=inf; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(g[i][j]=='#') { s1.x=i,s1.y=j; for(int ii=0; ii<n; ii++) { for(int jj=0; jj<m; jj++) { if(g[ii][jj]=='#') { s2.x=ii,s2.y=jj; int tmp=bfs(); ans=min(tmp,ans); } } } } } } cout<<"Case "<<++cas<<": "; if(ans==inf) cout<<-1<<endl; else cout<<ans<<endl; } return 0; }