题目大意: 给你一个n*m的图,里面有草也有空地(#代表草)。现在有两个人各在一块草地点火要烧掉这些草,并且燃烧的草可以向上下左右四个方向蔓延,问最少多长时间可以将所有的草都烧完,不能全部烧完输出-1.
两个起点的BFS,感觉和求最短路差不多,依次枚举两个起点,找到步数最多的那个草地,再从每次枚举的结果中找最小的。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<cstring> #include<string> #define maxn 9999999 using namespace std; char a[11][11]; int vis[11][11],ans[11][11]; int n,m,cnt; typedef struct { int x,y; }Point; int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; int bfs(int x1,int y1,int x2,int y2) { Point f1,f2; queue<Point>q; memset(ans,maxn,sizeof(ans)); f1.x=x1,f1.y=y1; f2.x=x2,f2.y=y2; ans[x1][y1]=0,ans[x2][y2]=0; vis[x1][y1]=1,vis[x2][y2]=1; q.push(f1); q.push(f2); while(!q.empty()) { f1=q.front(); q.pop(); for(int i=0;i<4;i++) { f2.x=f1.x+next[i][0]; f2.y=f1.y+next[i][1]; if(vis[f2.x][f2.y]==0&&a[f2.x][f2.y]==‘#‘&&f2.x>=0&&f2.x<n&&f2.y>=0&&f2.y<m) { ans[f2.x][f2.y]=ans[f1.x][f1.y]+1; q.push(f2); vis[f2.x][f2.y]=1; } } } int ma=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(a[i][j]==‘#‘) ma=ma>ans[i][j]?ma:ans[i][j]; return ma; } int main() { int t; scanf("%d",&t); int g=0; while(t--) { int mi=maxn; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",a[i]); cnt=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(a[i][j]==‘#‘) cnt++; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { for(int k=0;k<n;k++) for(int l=0;l<m;l++) { if(a[i][j]==‘#‘&&a[k][l]==‘#‘) { int c; memset(vis,0,sizeof(vis)); c=bfs(i,j,k,l); mi=mi<c?mi:c; } } } if(mi==maxn) printf("Case %d: -1\n",++g); else printf("Case %d: %d\n",++g,mi); } return 0; }
时间: 2024-12-25 18:54:25