# P2895 [USACO08FEB] Meteor Shower S
## 题目描述
贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。
如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。
根据预报,一共有 $M$ 颗流星 $(1\leq M\leq 50,000)$ 会坠落在农场上,其中第 $i$ 颗流星会在时刻 $T_i$($0 \leq T _ i \leq 1000$)砸在坐标为 $(X_i,Y_i)(0\leq X_i\leq 300$,$0\leq Y_i\leq 300)$ 的格子里。流星的力量会将它所在的格子,以及周围 $4$ 个相邻的格子都化为焦土,当然贝茜也无法再在这些格子上行走。
贝茜在时刻 $0$ 开始行动,她只能在会在横纵坐标 $X,Y\ge 0$ 的区域中,平行于坐标轴行动,每 $1$ 个时刻中,她能移动到相邻的(一般是 $4$ 个)格子中的任意一个,当然目标格子要没有被烧焦才行。如果一个格子在时刻 $t$ 被流星撞击或烧焦,那么贝茜只能在 $t$ 之前的时刻在这个格子里出现。 贝茜一开始在 $(0,0)$。
请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。如果不可能到达输出 $−1$。
## 输入格式
共 $M+1$ 行,第 $1$ 行输入一个整数 $M$,接下来的 $M$ 行每行输入三个整数分别为 $X_i, Y_i, T_i$。
## 输出格式
贝茜到达安全地点所需的最短时间,如果不可能,则为 $-1$。
## 输入输出样例 #1
### 输入 #1
```
4
0 0 2
2 1 2
1 1 2
0 3 5
```### 输出 #1
```
5
```
#include<bits/stdc++.h>
using namespace std;
const int N =305;
int gt[N][N];
int st[N][N];
int dist[N][N];
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
typedef pair<int,int> PII;
queue<PII> q;
int m;
int bfs(int x,int y)
{
memset(dist,-1,sizeof(dist));
dist[x][y]=0;
q.push({x,y});
while(q.size())
{
auto t=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int a=t.first+dx[i],b=t.second+dy[i];
if(a<0||b<0) continue; //边界
if(dist[a][b]!=-1) continue; //访问过的点
if(gt[a][b]<=dist[t.first][t.second]+1) continue; //格子化为焦土 时间等于也不可以
q.push({a, b});
dist[a][b]=dist[t.first][t.second]+1;
if (gt[a][b] >= 1000000000 ) return dist[a][b];
}
}
return -1;
}
int main()
{
cin>>m;
memset(gt,0x3f3f3f3f,sizeof(gt)); //把安全的地方全部初始化为一个极大的数
for(int i=1;i<=m;i++)
{
int x,y,t;
cin>>x>>y>>t;
gt[x][y]=min(t,gt[x][y]); //当有第二个流星落到同样的格子时,时间应该去最小值
for(int j=0;j<4;j++)
{
int a=x+dx[j],b=y+dy[j];
if(a>=0&&a<=300&&b>=0&&b<=300)
gt[a][b]=min(t,gt[a][b]); //蔓延四个格子同理
}
}
int res=bfs(0,0);
cout<<res;
return 0;
}