poj 3669 (BFS)

来源:互联网 发布:电信网络优化工程师 编辑:程序博客网 时间:2024/05/17 01:54

 题目链接http://poj.org/problem?id=3669

这道题跟我其实有很深的渊源呀,第一次做的时候用的是模拟法,就是对流星下落的时间进行排序,然后模拟每个流星下落的过程,以及人的运动,十分繁琐,经过了WA,RE,最后一直TLE过不了...... 之后放了有一个月,这几天又拿出来,想了一个更简洁的方法,最后AC掉。

思路先将Map初始化为INF,然后将每颗流星下落的时间标记在Map上,对于同一位置多颗流星撞击,取其中的最小值,然后从起始位置进行宽度优先搜索,直到找到位置上为INF位置。

这道题同时也体现出细节的力量,BFS中有一个细节,就是判断当前状态是否是INF状态,

一种是在从队列中取出状态的时候,

    while(que.size()){       Bes=que.front();       que.pop();       if(Map[Bes.x][Bes.y]==INF) return Bes.t;       Map[Bes.x][Bes.y]=0;       for(int i=0;i<4;i++){            iii mid;            mid.x=Bes.x+dir[i][0];            mid.y=Bes.y+dir[i][1];            mid.t=Bes.t+1;            if(mid.t<Map[mid.x][mid.y]) que.push(mid);       }    }

 

一种是在加入队列之前,

 

    while(que.size()){       Bes=que.front();       que.pop();       for(int i=0;i<4;i++){            iii mid;            mid.x=Bes.x+dir[i][0];            mid.y=Bes.y+dir[i][1];            mid.t=Bes.t+1;            if(Map[mid.x][mid.y]==INF) return mid.t;            if(Map[mid.x][mid.y]<=mid.t) continue;            Map[mid.x][mid.y]=0;            que.push(mid);       }    }

 


这两种不同的方法在运行时间上相差很大,不知道是题的原因还是本身就存在差异,我先是用的第一种方法,结果一直是TLE,感觉实在无解,去搜了题解直到了第二种方法,结果94ms就过了~~~~

还有一些细节见code了

code:

//poj 3669//广度优先搜索#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <iostream>#include <queue>using namespace std;#define SIZE 405//注意范围,题目给的范围是流星的范围并不是活动的范围,所以数组应该开得更大一些#define INF 10000000struct NODE{    int x,y,t;};typedef struct NODE iii;int Map[SIZE][SIZE];int dir[5][2]={{0,1},{0,-1},{-1,0},{1,0},{0,0}}; //表示上 下 左 右 中五个方向queue<iii> que;// 在此申请了一个iii类型的队列iii Bes;void initial(){    for(int i=0;i<SIZE;i++){        for(int j=0;j<SIZE;j++){            //为了防止出界 将活动区域之外 又围了一圈            if(!i||!j||(i==SIZE-1)||(j==SIZE-1)) Map[i][j]=0;            else Map[i][j]=INF;        }    }    Bes.x=1;//因为活动区域的变化 所以其实位置也得变化    Bes.y=1;    Bes.t=0;    que.push(Bes);    int midx,midy,midt,N; //用于输入时对地图的处理    scanf("%d",&N);    while(N--){        scanf("%d%d%d",&midx,&midy,&midt);        midx++;//为了防止越界 全部都是x,y都是从1开始的        midy++;        for(int i=0;i<5;i++){            if(Map[midx+dir[i][0]][midy+dir[i][1]]>midt){                Map[midx+dir[i][0]][midy+dir[i][1]]=midt;            }        }    }    return ;}int BFS(){    if(Map[1][1]==0) return -1;    if(Map[1][1]==INF) return 0;    while(que.size()){       Bes=que.front();       que.pop();       for(int i=0;i<4;i++){            iii mid;            mid.x=Bes.x+dir[i][0];            mid.y=Bes.y+dir[i][1];            mid.t=Bes.t+1;            if(Map[mid.x][mid.y]==INF) return mid.t;            if(Map[mid.x][mid.y]<=mid.t) continue;            Map[mid.x][mid.y]=0;            que.push(mid);       }    }    return -1;}int main(){    initial();    printf("%d\n",BFS());    return 0;}

 

0 0
原创粉丝点击