poj 3669 Meteor Shower (bfs)

题目链接:点击打开链接


题意:

M个陨石会在某个时间砸向地图某点,摧毁该点及其上下左右总共五个格子,也就是在这个时间以后这些

格子就不能通过了,问主人公从(0,0)开始最少需要多少时间能到达安全的地方(也就是一直不会被摧

毁的地方)


先初始化所以格子的崩塌时间为INF(无限大),然后预处理出所有的时间。

再BFS,如果没越界、没访问过而且 到达这点的时间<陨石摧毁这点的时间,就可以走。

将这样的点入队列,如果从队列取出的点的 崩塌时间为无穷大,则返回到这点的时间,即为结果。


比赛的时候 思路没理清,想把崩塌时间和BFS时的到达时间混在一起,只用一个vis[][]处理修改

其值。这样不好弄。


注意点:崩塌点上下左右5个点可能超过了300的范围。所以边界判断上界要稍微大点取。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;

struct node
{
    int x,y;
    int t;
}h;

int bt[310][310];
bool vis[310][310];

int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};

queue<node> q;

int bfs()
{
    while(!q.empty())
        q.pop();
    h.x=0,h.y=0;
    h.t=0;
    q.push(h);
    vis[h.x][h.y]=true;

    node cur,next;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();

        if(bt[cur.x][cur.y]==INF)
           return cur.t;
        for(int i=0;i<4;i++)
        {
            next.x=cur.x+dx[i];
            next.y=cur.y+dy[i];
            next.t=cur.t+1;

            if(next.x>=0 && next.x<305 && next.y>=0 && next.y<305)
            {
                if(!vis[next.x][next.y] && bt[next.x][next.y]>next.t)
                {
                    q.push(next);
                    vis[next.x][next.y]=true;
                }
            }
        }
    }
    return -1;
}

int main()
{
    int m,x,y,t;
    while(scanf("%d",&m)!=EOF)
    {
        memset(bt,INF,sizeof(bt));

        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&t);

            if(bt[x][y]>t)
                bt[x][y]=t;
            for(int k=0;k<4;k++)
            {
                int xx=x+dx[k];
                int yy=y+dy[k];
                if(xx>=0 && xx<305 && yy>=0 && yy<305 && bt[xx][yy]>t)
                    bt[xx][yy]=t;
            }
        }
        memset(vis,0,sizeof(vis));
        int flag=bfs();
        printf("%d\n",flag);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值