您的位置:首页 > 其它

POJ 3669 Meteor Shower

2017-06-27 15:19 323 查看
题意:m颗流星,流星袭击点(x,y)的时间为t,袭击时会破坏点(x,y)及其周围上下左右的点,被破坏的点就不能再走了,人开始时位于原点处,人每走一步时间加1,求人到达安全地方的最短时间,若无法到达安全地方则输出-1,安全地方就是一直不会被袭击的点。

解题思路:广搜bfs.求最短时间,类似于迷宫问题。首先构建出图,并将移动到图中所有点的最短时间和该点被袭击的时间初始化为INF,每个点被袭击的时间可能有重叠情况,所以这里要取被袭击的最小时间。对于约束条件就是下一步也就是下一时刻移动到的点是否被破坏,如果没有被破坏则满足条件,具体见代码注释。

代码:

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

#define INF 0x3f3f3f3f
int dr[]= {0,0,1,-1};
int dc[]= {1,-1,0,0};
int g[305][305],d[305][305];
int m;
struct Node
{
int x,y;
Node(int a=0,int b=0):x(a),y(b) {}
};
bool inside(int x,int y)
{
return x>=0&&x<305&&y>=0&&y<305;
}
int bfs(int x,int y)
{
queue<Node> q;
for(int i=0; i<305; i++)
{
for(int j=0; j<305; j++)
{
d[i][j]=INF;//将移动到该点的最短时间初始化为INF
}
}
q.push(Node(x,y));
d[x][y]=0;
while(!q.empty())
{
Node now=q.front();
q.pop();
if(g[now.x][now.y]==INF)return d[now.x][now.y];//g[x][y]=INF说明该点一直未被袭击,g[x][y]表示袭击时间
for(int i=0; i<4; i++)
{
int nx=now.x+dr[i],ny=now.y+dc[i];
if(inside(nx,ny)&&g[nx][ny]>d[now.x][now.y]+1&&d[nx][ny]==INF)//约束条件,看下一时刻移动到的点是否被破坏
{
q.push(Node(nx,ny));
d[nx][ny]=d[now.x][now.y]+1;
}
}
}
return -1;
}
int main()
{
cin>>m;
for(int i=0; i<305; i++)
{
for(int j=0; j<305; j++)
{
g[i][j]=INF;//将袭击该点时间初始化为INF
}
}
for(int i=0; i<m; i++)
{
int a,b,c;
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);//如果破坏范围重叠,则破坏时间为较早的时间
for(int j=0; j<4; j++)//对四周的点造成破坏的时间
{
int nx=a+dr[j],ny=b+dc[j];
if(inside(nx,ny))
g[nx][ny]=min(g[nx][ny],c);
}
}
cout<<bfs(0,0)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bfs