这是一道比较基础的BFS的题目。和其他题目不同的是,这道题需要初始化一下每个格子起火的时间。
这几天参加比赛,发现,算法死套模板真的不对,要灵活运用,发挥自己智慧的大脑,才能有更优秀的算法的应用!
还有,分析问题的能力也真的很重要,一道题目可能说得很长,但是最有用的只有那么几句话,从那几句话中再提炼出来一些实质性的东西,就是解题的思路了!
想这道题,实际上就是两次求最短路径,第一次求最短路径,限制第二次求最短路径!还有一个思想就是超级源,这是一个比较比片的思想在解题的过程中,网络会用得比较多。
这里就是将开始时间,所有起火的点都放入队列,并且最短路径设为了0,相当于将它们都视为起点
具体代码如下:
#include <cstdio>
#include <vector>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 1010;
const int INF = 100000;
int T, n, m, ans;
int tim[N][N], d[N][N];
int a[4] = { 0, 0, 1, -1 }, b[4] = { 1, -1, 0, 0 };
char g[N][N];
queue <pair<int, int> > q;
pair<int,int> S, u, tmp;
void initTime() {
while ( !q.empty() ) {
u = q.front(); q.pop();
int ux = u.first, uy = u.second;
for ( int i = 0; i < 4; ++i ) {
int x = ux + a[i], y = uy + b[i];
if ( tim[x][y] > tim[ux][uy] + 1 && g[x][y] != '#' ) {
tim[x][y] = tim[ux][uy] + 1;
tmp.first = x, tmp.second = y;
q.push( tmp );
}
}
}
}
void Bfs() {
d[S.first][S.second] = 0;
queue<pair<int, int> > Q;
Q.push( S ); ans = INF;
while ( !Q.empty() ) {
u = Q.front(); Q.pop();
int ux = u.first, uy = u.second;
//cout << ux << ' ' << uy << endl;
if ( ux == 1 || ux == n || uy == 1 || uy == m ) {
ans = d[ux][uy];
break;
}
for ( int i = 0; i < 4; ++i ) {
int x = ux + a[i], y = uy + b[i];
if ( g[x][y] == '.' && d[x][y] > d[ux][uy] + 1 && d[ux][uy] + 1 < tim[x][y] ) {
d[x][y] = d[ux][uy] + 1;
//cout << d[x][y] << ' ' << time[x][y] << "zuobiao " << x << ' ' << y << endl;
tmp.first = x, tmp.second = y;
Q.push(tmp);
}
}
}
}
int main()
{
scanf("%d", &T);
while ( T-- ) {
while ( !q.empty() ) q.pop();
scanf("%d%d", &n, &m); getchar();
for ( int i = 0; i <= n+1; ++i ) g[i][0] = g[i][m+1] = '#';
for ( int j = 0; j <= m+1; ++j ) g[0][j] = g[n+1][j] = '#';
for ( int i = 0; i <= n; ++i ) for ( int j = 0; j <= m; ++j ) tim[i][j] = d[i][j] = INF;
for ( int i = 1; i <= n; ++i, getchar() )
for ( int j = 1; j <= m; ++j ) {
scanf("%c", &g[i][j]);
if ( g[i][j] == 'F' ) {
tmp.first = i, tmp.second = j;
tim[i][j] = 0;
q.push(tmp);
}
else if ( g[i][j] == 'J' ) S.first = i, S.second = j;
}
initTime();
//for ( int i = 1; i <= n; ++i, cout << endl ) for ( int j = 1; j <= m; ++j ) cout << time[i][j] << " ";
Bfs();
//for ( int i = 1; i <= n; ++i, cout << endl ) for ( int j = 1; j <= m; ++j ) cout << d[i][j] << " ";
if ( ans == INF ) printf("IMPOSSIBLE\n");
else printf("%d\n", ans+1);
}
}