poj 3669 Meteor Shower(广度优先搜索)

题目链接:点击打开链接


用des数组保存每个格子被炸的最早时间,如果是inf就说明始终没被炸。在搜索时每次将当前格子的4个方向上合法的格子推入队列,如果走到始终没被炸的格子就说明已经到安全地址了,如果遇到没路走了的情况就输出-1


坑:虽然地图范围是300,但是301这个位置也是合法的,并且会影响300这个点,所以判断时要判断到300这个位置。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define INF 10000000
#include <queue>
using namespace std;

int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int des[305][305];
int vis[305][305];
struct node{
    int x,y,t;
    node(){}
    node(int x,int y,int t):x(x),y(y),t(t){}
};
bool C(node t){
    if(vis[t.x][t.y]||t.x<0||t.y<0||t.x>301||t.y>301||t.t>=des[t.x][t.y])
        return 0;
    return 1;
}


int main(){
    int M;
    scanf("%d",&M);
    for(int i=0;i<=301;i++){
        for(int j=0;j<=301;j++){
            des[i][j]=INF;
        }
    }

    for(int i=1;i<=M;i++){
        int x,y,t;
        scanf("%d%d%d",&x,&y,&t);
        des[x][y]=min(des[x][y],t);
        for(int i=0;i<4;i++){
            int tx=x+dis[i][0];
            int ty=y+dis[i][1];
            if(tx>=0&&tx<=300&&ty>=0&&ty<=300)
                 des[tx][ty]=min(des[tx][ty],t);
        }
    }
    queue <node> q;
    bool flag=0;
    int res;
    q.push(node(0,0,0));
    vis[0][0]=1;
    while(!q.empty()){
        node t=q.front();
        if(des[t.x][t.y]==INF){
            flag=1;
            res=t.t;
            break;
        }
        q.pop();
        for(int i=0;i<4;i++){
            node tmp=node(t.x+dis[i][0],t.y+dis[i][1],t.t+1);
            if(C(tmp)){
                q.push(tmp);
                vis[tmp.x][tmp.y]=1;
            }
        }
    }
    if(flag) printf("%d",res);
    else printf("-1");
    return 0;
}







你可能感兴趣的:(广度优先搜索)