poj3669Meteor Shower(bfs)

题目请戳这里

题目大意:在二维平面上,有个人一开始在原点,现在有一场流星雨,已知有n个,第i个流星第ti秒落在(xi,yi)位置,并且(xi,yi)周围4个位置也会遭殃.人每秒走单位长度,并且只能向四个方向走,并且走的位置要在流行毁灭这一点之前.求这个人最快脱险时间.无法脱险输出-1.

题目分析:简单搜索,bfs妥妥的得意.首先用flag数组记录下所有位置最先遭殃的时间.然后从源点开始bfs.直到找到一个安全的地点为止.

trick:题目描述有误,二维平面范围不止300!要大一点!!

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 402;
const int M = 50005;
const int NM = 50004;
const int inf = 0x3f3f3f3f;
struct node
{
    int x,y,t;
    bool operator< (const node a)const
    {
        return t < a.t;
    }
}pt[M],que[NM],ss,now;
int flag[N][N];
bool vis[N][N];
int dir[4][2] = {{-1,0},{0,-1},{0,1},{1,0}};
int n;

bool isok(int x,int y)
{
    return (x >= 0 && y >= 0 && x <= 400 && y <= 400);
}

int bfs()
{
    ss.x = ss.y = ss.t = 0;
    int i,head,tail;
    head = tail = 0;
    que[tail ++] = ss;
    vis[0][0] = true;

    while(head != tail)
    {
        now = que[head ++];
        if(head == NM)
            head = 0;
        if(flag[now.x][now.y] == inf)
            return now.t;
        ss = now;
        ss.t ++;
        for(i = 0;i < 4;i ++)
        {
            ss.x = now.x + dir[i][0];
            ss.y = now.y + dir[i][1];
            if(vis[ss.x][ss.y] || !isok(ss.x,ss.y))
                continue;
            if(flag[ss.x][ss.y] == inf)
                return ss.t;
            if(ss.t < flag[ss.x][ss.y])
            {
                vis[ss.x][ss.y] = true;
                que[tail ++] = ss;
                if(tail == NM)
                    tail = 0;
            }
        }
    }
    return -1;
}

int main()
{
    int i,j;
    while(scanf("%d",&n) != EOF)
    {
        memset(flag,0x3f,sizeof(flag));
        memset(vis,false,sizeof(vis));
        for(i = 0;i < n;i ++)
        {
            scanf("%d%d%d",&pt[i].x,&pt[i].y,&pt[i].t);
            flag[pt[i].x][pt[i].y] = min(flag[pt[i].x][pt[i].y],pt[i].t);
            for(j = 0;j < 4;j ++)
            {
                if(isok(pt[i].x + dir[j][0],pt[i].y + dir[j][1]))
                    flag[pt[i].x + dir[j][0]][pt[i].y + dir[j][1]] = min(pt[i].t,flag[pt[i].x + dir[j][0]][pt[i].y + dir[j][1]]);
            }
        }
        printf("%d\n",bfs());
    }
    return 0;
}


你可能感兴趣的:(搜索,bfs)