題目鏈接
‘#’表示草坪,‘ . ’表示空地,然後可以選擇在任意的兩個草坪格子點火,火勢每一秒會向周圍四個格子擴散,問選擇那兩個點使得燃燒所有的草坪花費的時間最小。
暴力枚舉任意的草坪所在的點,然後兩個點壓進隊列裏面BFS,找一個滿足條件的最小值即可。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<set>
#include<vector>
using namespace std;
struct node
{
int x,y;
int step;
node(){}
node(int xx,int yy,int ss):x(xx),y(yy),step(ss){}
};
int n,m;
int vis[20][20];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char mp[20][20];
int bfs(node s1,node s2)
{
int ans=0;
queue<node> q;
q.push(s1);
q.push(s2);
vis[s1.x][s1.y]=1;
vis[s2.x][s2.y]=1;
while(!q.empty())
{
node now=q.front();
q.pop();
ans=now.step;
node next;
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
if(next.x<0||next.x>n||next.y<0||next.y>m)
continue;
if(vis[next.x][next.y]||mp[next.x][next.y]!='#')
continue;
next.step=now.step+1;
vis[next.x][next.y]=1;
q.push(next);
}
}
return ans;
}
bool check()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='#'&&vis[i][j]==0)
return false;
}
}
return true;
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
for(int t=1;t<=T;t++)
{
vector<node> v;
memset(mp,0,sizeof(mp));
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>mp[i][j];
if(mp[i][j]=='#')
v.push_back(node(i,j,0));
}
int len=v.size();
int ans=0x3f3f3f3f;
for(int i=0;i<len;i++)
{
for(int j=i;j<len;j++)
{
memset(vis,0,sizeof(vis));
int num=bfs(v[i],v[j]);
if(check())
ans=min(num,ans);
}
}
cout<<"Case "<<t<<": ";
if(ans!=0x3f3f3f3f)
cout<<ans<<endl;
else
cout<<-1<<endl;
}
return 0;
}