BFS - Barareh on Fire+Fire!
题目1:Barareh on Fire(UVALive 8235)
UVALive 8235
题目链接:
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2031
题目:
Description
The Barareh village is on fire due to the attack of the virtual enemy. Several places are already on fire and the fire is spreading fast to other places. Khorzookhan who is the only person remaining alive in the war with the virtual enemy, tries to rescue himself by reaching to the only helicopter in the Barareh villiage. Suppose the Barareh village is represented by an n × m grid. At the initial time, some grid cells are on fire. If a cell catches fire at time x, all its 8 vertex-neighboring cells will catch fire at time x + k. If a cell catches fire, it will be on fire forever. At the initial time, Khorzookhan stands at cell s and the helicopter is located at cell t. At any time x, Khorzookhan can move from its current cell to one of four edge-neighboring cells, located at the left, right, top, or bottom of its current cell if that cell is not on fire at time x + 1. Note that each move takes one second. Your task is to write a program to find the shortest path from s to t avoiding fire.
Input
There are multiple test cases in the input. The first line of each test case contains three positive integers n, m and k (1 ⩽ n,m,k ⩽ 100), where n and m indicate the size of the test case grid n × m, and k denotes the growth rate of fire. The next n lines, each contains a string of length m, where the jth character of the ith line represents the cell (i, j) of the grid. Cells which are on fire at time 0, are presented by character “f”. There may exist no “f” in the test case. The helicopter and Khorzookhan are located at cells presented by “t” and “s”, respectively. Other cells are filled by “-” characters. The input terminates with a line containing “0 0 0” which should not be processed.
Output
For each test case, output a line containing the shortest time to reach t from s avoiding fire. If it is impossible to reach t from s, write “Impossible” in the output.
Sample Input
7 7 2
f------
-f---f-
----f--
-------
------f
---s---
t----f-
3 4 1
t--f
--s-
----
2 2 1
st
f-
2 2 2
st
f-
0 0 0
Sample Output
4
Impossible
Impossible
1
题意or解题思路
运用两次BFS
第一次BFS 找出每个地方火到达的最短时间用一个数组tim来保存 (注意数组名不能用time 否则会CE)
第二次BFS 找到人逃出去的最短路径 如果不能逃出去即队列里的元素为空
走的时候要用tim数组判断火是否已经到达该点
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int n,m,k,tim[105][105],vis[105][105];
int dfx[8]= {0,0,1,-1,1,1,-1,-1};//火蔓延的八个方向
int dfy[8]= {1,-1,0,0,1,-1,1,-1};
int dx[4]= {0,0,1,-1};//人走的四个方向
int dy[4]= {1,-1,0,0};
char pic[105][105];
struct node
{
int x,y,step;
};
void bfs1()
{
queue<node>p;
node b,now,next;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(pic[i][j]=='f')
{
tim[i][j]=0;
b.x=i;
b.y=j;
b.step=0;//火走的时间
p.push(b);
}
}
while(!p.empty())
{
now=p.front();
p.pop();
for(int d=0; d<8; d++)
{
next=now;
next.x+=dfx[d];
next.y+=dfy[d];
if(next.x<0||next.x>=n||next.y<0||next.y>=m)continue;//越界
next.step=now.step+k;
if(next.step<tim[next.x][next.y])//需要判断现在的时间和tim数组里时间的大小如果小就重新对tim赋值 再入队
{
tim[next.x][next.y]=next.step;
p.push(next);
}
}
}
}
void bfs2(int xx,int yy)
{
queue<node>q;
node b,now,next;
b.x=xx;
b.y=yy;
b.step=0;
vis[xx][yy]=1;
q.push(b);
while(!q.empty())
{
now=q.front();
q.pop();
if(pic[now.x][now.y]=='t')
{
printf("%d\n",now.step);
return ;
}
for(int d=0; d<4; d++)
{
next=now;
next.x+=dx[d];
next.y+=dy[d];
next.step++;
if(next.x<0||next.x>=n||next.y<0||next.y>=m)continue;//越界
if(vis[next.x][next.y]!=1&&next.step<tim[next.x][next.y])//没走过且火还没有蔓延到这一点标记+入队
{
vis[next.x][next.y]=1;
q.push(next);
}
}
}
printf("Impossible\n");
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if(n==0||m==0||k==0)break;
getchar();
memset(tim,0x3f3f3f3f,sizeof(tim)); //用一个很大很大的值付给 tim
memset(vis,0,sizeof(vis));
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
scanf("%c",&pic[i][j]); //将图输入
}
getchar();
}
bfs1();
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(pic[i][j]=='s') //找到起点
{
bfs2(i,j);
break;
}
}
}
return 0;
}
题目二:Fire!(UVA 11624)
题目链接:
https://vjudge.net/problem/UVA-11624
题目:
Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze.
Given Joe’s location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it. Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire.
Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the fire may enter a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test cases to follow. The first line of each test case contains the two integers R and C, separated by spaces, with 1 ≤ R, C ≤ 1000. The following R lines of the test case each contain one row of the maze. Each of these lines contains exactly C characters, and each of these characters is one of:
• #, a wall
• ., a passable square
• J, Joe’s initial position in the maze, which is a passable square
• F, a square that is on fire There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
Sample Output
3
IMPOSSIBLE
注意:
只要能走到地图的边缘就可以出去
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int t,r,c,vis[1005][1005],tim[1005][1005];
char pic[1005][1005];
int dx[4]= {0,0,1,-1};
int dy[4]= {1,-1,0,0};
struct node
{
int x,y,step;
};
void bfs1()
{
queue<node>p;
node b,now,next;
for(int i=0; i<r; i++)
for(int j=0; j<c; j++)
{
if(pic[i][j]=='F')
{
b.x=i;
b.y=j;
b.step=0;
tim[i][j]=0;
p.push(b);
}
}
while(!p.empty())
{
now=p.front();
p.pop();
for(int d=0; d<4; d++)
{
next=now;
next.x+=dx[d];
next.y+=dy[d];
next.step++;
if(next.x<0||next.y<0||next.x>=r||next.y>=c)continue;
if(next.step<tim[next.x][next.y]&&pic[next.x][next.y]!='#')
{
tim[next.x][next.y]=next.step;
p.push(next);
}
}
}
}
void bfs2(int xx,int yy)
{
queue<node>q;
node b,now,next;
b.x=xx;
b.y=yy;
b.step=0;
vis[xx][yy]=1;
q.push(b);
while(!q.empty())
{
now=q.front();
q.pop();
if(now.x==0||now.x==r-1||now.y==0||now.y==c-1)
{
printf("%d\n",now.step+1);
return;
}
for(int d=0; d<4; d++)
{
next=now;
next.x+=dx[d];
next.y+=dy[d];
next.step++;
if(pic[next.x][next.y]=='#')continue;
if(now.x<0||now.y<0||now.y>=c||now.x>=r)continue;
if(next.step<tim[next.x][next.y]&&vis[next.x][next.y]==0)
{
vis[next.x][next.y]=1;
q.push(next);
}
}
}
printf("IMPOSSIBLE\n");
return;
}
int main()
{
scanf("%d",&t);
for(int tt=0; tt<t; tt++)
{
scanf("%d %d",&r,&c);
getchar();
memset(tim,0x3f3f3f3f,sizeof(tim));
memset(vis,0,sizeof(vis));
memset(pic,' ',sizeof(pic));
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
scanf("%c",&pic[i][j]);
getchar();
}
bfs1();
for(int i=0; i<r; i++)
for(int j=0; j<c; j++)
{
if(pic[i][j]=='J')
{
bfs2(i,j);
break;
}
}
}
return 0;
}