题意:
同时从两个点点火,火焰每秒会扩散到上下左右四个方向,问是都能把草地全部点燃,若能,请输出最短时间,若不能输出-1
思路:
先深搜有几个连通块,若>2,怎不可能全部烧完,输出-1
若<=2,怎枚举两个起点(可以为同一点,用一个思维数组标记),算出每种情况下的最长时间,再在这些最长时间里选择最短的
代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 1e7+9
typedef long long ll;
const int N = 1e5;
int n, m, ans, sum;
char map[15][15];
int vis[15][15], v[15][15][15][15];
queue<pair<int, int> >q;
int f[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void dfs(int a, int b)
{
vis[a][b] = 1;
for(int i = 0; i < 4; i++)
{
int x = a + f[i][0];
int y = b + f[i][1];
if(x >= 0 && x < n && y >= 0 && y < m && map[x][y] == '#' && vis[x][y] == 0)
{
dfs(x, y);
}
}
}
void bfs(int x1, int y1, int x2, int y2)
{
memset(vis, 0, sizeof(vis));
while(!q.empty()) q.pop();
q.push(make_pair(x1, y1));
q.push(make_pair(x2, y2));
vis[x1][y1] = 1;
vis[x2][y2] = 1;
sum = 1;
while(!q.empty())
{
pair<int, int>a = q.front();
q.pop();
int x = a.first;
int y = a.second;
for(int i = 0; i < 4; i++)
{
int tx = x + f[i][0];
int ty = y + f[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(map[tx][ty] == '#' && !vis[tx][ty])
{
vis[tx][ty] = vis[x][y] + 1;
q.push(make_pair(tx, ty));
if(sum < vis[tx][ty]) sum = vis[tx][ty];
}
}
}
}
bool judge()//判断是否全部点着
{
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(map[i][j] == '#' && !vis[i][j])
return false;
return true;
}
int main()
{
int t;
scanf("%d", &t);
int cas = 1;
while(t--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)
scanf("%s", map[i]);
memset(vis, 0, sizeof(vis));
ans = 0;
for(int i = 0; i < n; i++)//判断连通块
{
for(int j = 0; j < m; j++)
{
if(map[i][j] == '#' && vis[i][j] == 0)
{
dfs(i, j);
ans++;
}
}
}
printf("Case %d: ", cas++);
if(ans > 2){puts("-1"); continue;}
memset(v, 0, sizeof(v));
ans = INF;
while(!q.empty()) q.pop();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(map[i][j] != '#')continue;
for(int p = 0; p < n; p++)
{
for(int q = 0; q < m; q++)
{
if(map[p][q] == '#' && v[i][j][p][q] == 0)
{
v[i][j][p][q] = 1, v[p][q][i][j] = 1;
bfs(i, j, p, q);
if(judge() && sum - 1 < ans) ans = sum - 1;
}
}
}
}
}
printf("%d\n", ans);
}
return 0;
}