人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
BFS经典题
- 用BFS(0, 0), 直到到达安全地点;
- 用二维数组m[][]表示每个点的爆炸时间,初始化为INF,表示不会爆炸,在输入的同时对其初始化,并初始化其周围的4个点,维护其最小值;
- 当扫描到m[][] == INF时, 结束;
- 具体见代码;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
using namespace std;
const int INF=1<<30;
int d[5][2] = {{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int M;
int m[305][305];
// 最短存活时间,用BFS 起点为(0,0),终点为安全地带。
// m[][]表示各个地方被流星雨轰炸的时间,初始化为INF,即安全,输入的同时对其进行初始化,
// 特别注意,因爆炸波及5个单位,爆炸区域可能存在重叠,并且刚好爆炸和爆炸后都无发进入,
// 所以t[]总是取最小的爆炸时间点。
struct node
{
int x, y, t;
}p[50005];
int in(int x, int y)
{
if(x>=0 && y>=0) return 1;
return 0;
}
int bfs()
{
queue<node> q;
// 防止回流
if(m[0][0] > 0) q.push(node{0, 0, 0});
while(!q.empty())
{
node cur = q.front();
q.pop();
int &x = cur.x;
int &y = cur.y;
int &t = cur.t;
// 到达安全点
if(m[x][y] == INF) return t;
for(int i = 1; i < 5; i++)
{
int nx = x + d[i][0];
int ny = y + d[i][1];
// 在范围内且下一时刻不会爆炸
if(in(nx, ny) && t+1 < m[nx][ny])
{
// 防止回流
if(m[nx][ny] != INF) m[nx][ny] = t + 1;
q.push(node{nx, ny, t+1});
}
}
}
return -1;
}
void solve()
{
int ans = bfs();
printf("%d\n", ans);
}
int main()
{
fill(m[0], m[0] + 305*305, INF);
cin >> M;
for(int i = 0; i < M; i++)
{
scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].t);
for(int j = 0; j < 5; j++)
{
int nx = p[i].x + d[j][0];
int ny = p[i].y + d[j][1];
// 维护最小爆炸时间
if(in(nx, ny)) m[nx][ny] = min(m[nx][ny], p[i].t);
}
}
solve();
return 0;
}