您的位置:首页 > 其它

UVA 11624 Fire! 【经典bfs】

2018-02-26 21:30 447 查看
传送门

// 题意: 在迷宫里有几处地方着火了, 火势每秒向上下左右扩散, 然后有一个J的人在迷宫里, 问能否跑出迷宫(只要他到达了边界就算出迷宫了). 注意 火 与 人 都不能穿墙

思路: 我们做两次bfs, 第一次把所有的着火点进行bfs, 处理出每一个火可以蔓延到的地方的着火时间, 然后再对人进行一次bfs, 除了一些判断条件外再加上判断人到这个点的时间与着火事件比较一下, 如果到达的时间>=着火的时间就不能到达. 然后就行啦,….

说一个行为坑点吧, 如果你是把没有着火的地点另成的-1, 那么你在人的那就要特判掉, 否则会影响判断的, 所以最好还是初始化为inf最好. 博主因为这个卡了半天…….. 因为有可能墙会把火关起来……

AC Code

const int inf = 0x3f3f3f3f; //用这个可以直接mem
const int maxn = 1e3+5;
int fire[maxn][maxn], vis[maxn][maxn];
char maze[maxn][maxn];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int n, m;
struct node {
int x, y, step;
};
queue<node>q2;
void bfs1()
{
while(!q2.empty()) {
node u = q2.front();
q2.pop();

for (int i = 0 ; i < 4 ; i ++) {
int xx = u.x + dx[i];
int yy = u.y + dy[i];
if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
if (maze[xx][yy] == '#' || fire[xx][yy] != inf) continue;
fire[xx][yy] = u.step + 1;
q2.push(node{xx, yy, u.step+1});
}
}
}

void bfs2(int x, int y)
{
queue<node>q; Fill(vis, 0);
vis[x][y] = 1; q.push(node{x, y, 0});
while(!q.empty()) {
node u = q.front();
q.pop();
if(u.x == 1 || u.x == n || u.y == 1 || u.y == m) {
printf("%d\n",u.step + 1);
return ;
}
for(int i = 0 ; i < 4 ; i ++) {
int xx = u.x + dx[i];
int yy = u.y + dy[i];
if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
if (maze[xx][yy] != '.' || vis[xx][yy]) continue;
if (fire[xx][yy] <= u.step + 1) continue;
vis[xx][yy] = 1;
q.push(node{xx, yy, u.step + 1});
}
}
printf("IMPOSSIBLE\n");
}
void solve()
{
Fill(fire, inf); // 不用-1 是因为判断火势的时间和人走到该处的时间
// 有影响, 要么特判. 情况就是F被关起来了. J在外面.
scanf("%d%d", &n, &m);
for (int i = 1 ; i <= n ; i ++) {
scanf("%s", maze[i] + 1);
}
int sx, sy;
for (int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= m ; j ++) {
if (maze[i][j] == 'F') {
fire[i][j] = 0;
q2.push(node{i, j, 0});
}
else if (maze[i][j] == 'J') {
sx = i;
sy = j;
}
}
}
bfs1(); bfs2(sx, sy);
while(!q2.empty()) q2.pop();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: