Meteor Shower POJ - 3669

该博客介绍了一种使用BFS算法寻找从起点(0,0)到安全地点的最短存活时间的方法。在二维数组m[][]中,每个点的初始爆炸时间为INF,表示安全。通过输入数据更新爆炸时间,并维护周围点的最小值。BFS遍历过程中,遇到INF则结束。最终返回最短存活时间。
摘要由CSDN通过智能技术生成

人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
BFS经典题

  1. 用BFS(0, 0), 直到到达安全地点;
  2. 用二维数组m[][]表示每个点的爆炸时间,初始化为INF,表示不会爆炸,在输入的同时对其初始化,并初始化其周围的4个点,维护其最小值;
  3. 当扫描到m[][] == INF时, 结束;
  4. 具体见代码;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
using namespace std;
const int INF=1<<30;
int d[5][2] = {{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int M;
int m[305][305];

// 最短存活时间,用BFS 起点为(0,0),终点为安全地带。
// m[][]表示各个地方被流星雨轰炸的时间,初始化为INF,即安全,输入的同时对其进行初始化,
// 特别注意,因爆炸波及5个单位,爆炸区域可能存在重叠,并且刚好爆炸和爆炸后都无发进入,
// 所以t[]总是取最小的爆炸时间点。

struct node
{
	int x, y, t;
}p[50005];

int in(int x, int y)
{
	if(x>=0 && y>=0)  return 1;
	return 0;
}

int bfs()
{
	queue<node> q;
	// 防止回流
	if(m[0][0] > 0)  q.push(node{0, 0, 0});
	while(!q.empty())
	{
		node cur = q.front();
		q.pop();
		int &x = cur.x;
		int &y = cur.y;
		int &t = cur.t;
		// 到达安全点
		if(m[x][y] == INF)  return t;
		for(int i = 1; i < 5; i++)
		{
			int nx = x + d[i][0];
			int ny = y + d[i][1];
			// 在范围内且下一时刻不会爆炸
			if(in(nx, ny) && t+1 < m[nx][ny])
			{
			// 防止回流
				if(m[nx][ny] != INF)  m[nx][ny] = t + 1;
				q.push(node{nx, ny, t+1});
			}
		}
	}
	return -1;
}

void solve()
{
	int ans = bfs();
	printf("%d\n", ans);
}

int main()
{
	fill(m[0], m[0] + 305*305, INF);
	cin >> M;
	for(int i = 0; i < M; i++)
	{
		scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].t);
		for(int j = 0; j < 5; j++)
		{
			int nx = p[i].x + d[j][0];
			int ny = p[i].y + d[j][1];
			// 维护最小爆炸时间
			if(in(nx, ny))  m[nx][ny] = min(m[nx][ny], p[i].t);
		}
	}
	solve();
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值