题目链接:FZU 2150 Fire Game
BFS。
记录草地数位cnt,然后任选两块有草的地方开始往四周燃烧,燃烧一块草地cnt - 1,直到不能燃烧为止,记录下燃烧到最远草地的时间,也就是选择这两块草地作为起始点所需的最长燃烧时间。再选择两块草地,重复上述过程,从这些最长时间中选择最少的时间,如果怎么样选择都不能烧完(cnt > 0),输出-1。
注意有可能只有一块草地,此时肯定是不能选择两块的,这种情况需要特判一下。
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <stdio.h>
using namespace std;
const int MAX_N = 10 + 5;
char _map[MAX_N][MAX_N];
int T;
int n, m, cnt;
struct Node
{
int i, j;
};
Node node[MAX_N << 1];
queue <Node> q;
vector <Node> v;
bool vis[MAX_N][MAX_N];
int dis[MAX_N][MAX_N];
int fx[] = {0, -1, 1, 0};
int fy[] = {1, 0, 0, -1};
int _min, _max;
int num, tem;
void BFS()
{
while(!q.empty())
{
Node w = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int x = fx[i] + w.i;
int y = fy[i] + w.j;
if(!vis[x][y] && x < n && x >= 0 && y < m && y >= 0 && _map[x][y] == '#')
{
vis[x][y] = 1;
dis[x][y] = dis[w.i][w.j] + 1;
_max = max(_max, dis[x][y]);
tem--;
Node temp1;
temp1.i = x;
temp1.j = y;
q.push(temp1);
}
}
}
}
int main()
{
cin >> T;
num = 0;
while(T--)
{
v.clear();
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
cnt = 0;
_min = 9999999;
_max = 0;
cin >> n >> m;
for(int i = 0; i < n; i++)
{
cin >> _map[i];
for(int j = 0; j < m; j++)
{
if(_map[i][j] == '#')
{
cnt++;
Node nod;
nod.i = i;
nod.j = j;
v.push_back(nod);
}
}
}
tem = cnt;
int flag = 0;
int ans = 9999999;
if(v.size() == 1)
{
tem--;
q.push(v[0]);
vis[v[0].i][v[0].j] = 1;
dis[v[0].i][v[0].j] = 0;
BFS();
if(tem == 0)
{
flag = 1;
_min = min(_min, _max);
}
}
else
{
for(int i = 0; i < v.size(); i++)
{
for(int j = i ; j < v.size(); j++)
{
tem = cnt;
_max = 0;
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
tem--;
tem--;
q.push(v[i]);
q.push(v[j]);
vis[v[i].i][v[i].j] = 1;
dis[v[i].i][v[i].j] = 0;
vis[v[j].i][v[j].j] = 1;
dis[v[j].i][v[j].j] = 0;
BFS();
if(tem == 0)
{
flag = 1;
_min = min(_min, _max);
}
}
}
}
if(flag == 1)
printf("Case %d: %d\n", ++num, _min);
else
printf("Case %d: %d\n", ++num, -1);
}
return 0;
}
本文介绍了FZU2150FireGame问题的求解方法,通过使用BFS算法,计算草地燃烧的最远距离,解决草地燃烧问题。
5630

被折叠的 条评论
为什么被折叠?



