poj 3669 Meteor Shower

                                                                                                  Meteor Shower
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 16339   Accepted: 4293

Description

Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will crash into earth and destroy anything they hit. Anxious for her safety, she vows to find her way to a safe location (one that is never destroyed by a meteor) . She is currently grazing at the origin in the coordinate plane and wants to move to a new, safer location while avoiding being destroyed by meteors along her way.

The reports say that M meteors (1 ≤ M ≤ 50,000) will strike, with meteor i will striking point (XiYi) (0 ≤ X≤ 300; 0 ≤ Y≤ 300) at time Ti (0 ≤ Ti  ≤ 1,000). Each meteor destroys the point that it strikes and also the four rectilinearly adjacent lattice points.

Bessie leaves the origin at time 0 and can travel in the first quadrant and parallel to the axes at the rate of one distance unit per second to any of the (often 4) adjacent rectilinear points that are not yet destroyed by a meteor. She cannot be located on a point at any time greater than or equal to the time it is destroyed).

Determine the minimum time it takes Bessie to get to a safe place.

Input

* Line 1: A single integer: M
* Lines 2..M+1: Line i+1 contains three space-separated integers: XiYi, and Ti

Output

* Line 1: The minimum time it takes Bessie to get to a safe place or -1 if it is impossible.

Sample Input

4
0 0 2
2 1 2
1 1 2
0 3 5

Sample Output

5
题意: 牛Bessie想要躲避流星雨,于是准备乘飞机逃跑。首先已知有M颗流星,每颗流星的位置(x,y)以及下落的时间t都已知,牛的出发点位于坐标轴原点,现在牛想要跑到一个流星砸不到的点,问至少要花多少时间(牛在出发点的时间记为0,每走一步花1单位的时间)。
思路:首先用一张图来记录每一个点会被流星砸到的最早时间,若某点不会被砸到则可记为无穷大,之后广度优先搜索,对于每一个点,若在图的范围并且当前时间还没被流星砸到且没被访问过,那么访问,之后看一下该点是否安全,安全就退出搜索,否则将该点入队。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int N_MAX = 500;
int field[N_MAX][N_MAX];//标记好每个位置被流星砸的时间
bool visited[N_MAX][N_MAX];
int direction[5][2] = { {1,0},{-1,0},{0,1},{0,-1},{0,0} };
int last;
struct MM {
 int X, Y, T;
 bool operator<(const MM&b)const{
     return T < b.T;
 }
};
MM m[50003];
int bfs(const int &x1,const int &y1,const int&cur_T) {
    memset(visited, 0, sizeof(visited));
    visited[x1][y1] = true;
    queue<MM>que;MM cur;
    cur.X = x1;cur.Y = y1, cur.T = cur_T;
    que.push(cur);
    while (!que.empty()) {
        MM p = que.front();que.pop();
        for (int i = 0;i < 4;i++) {
            cur = p;
            cur.X = direction[i][0] + p.X; cur.Y = direction[i][1] + p.Y;
            cur.T++;
            if (cur.X>= 0 && cur.Y>= 0 && field[cur.X][cur.Y]>cur.T&&!visited[cur.X][cur.Y]) {
                visited[cur.X][cur.Y] = true;
                if (field[cur.X][cur.Y]>last)//说明这一点不会被炸到
                    return cur.T;
                que.push(cur);
            }
        }
    }
    return -1;
}
int main() {
    int M;
    scanf("%d",&M);
    for (int i = 0;i < M;i++) 
        scanf("%d%d%d",&m[i].X,&m[i].Y,&m[i].T);

    sort(m,m+M);//按流星砸的时间的先后顺序排
    last = m[M - 1].T;

    for (int i = 0;i < N_MAX;i++) {
        for (int j = 0;j < N_MAX;j++)
            field[i][j] = INT_MAX;
    }

    for (int i = 0;i < M;i++) {
        for (int j = 0;j < 5;j++) {
            int x = m[i].X + direction[j][0],y=m[i].Y+direction[j][1];
            if (x >= 0 && y >= 0 && field[x][y]>m[i].T)  field[x][y] = m[i].T; 
        }
    }

    if (field[0][0] == 0)
        cout << -1 << endl;
    else {
        cout << bfs(0,0,0) << endl;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/ZefengYao/p/5935161.html