百练 / 2017大数据研究中心夏令营上机考试 F: Meteor Shower

题目来源:http://poj.org/problem?id=3669

F: Meteor Shower

总时间限制1000ms   内存限制65536kB

描述

Bessie hears that anextraordinary meteor shower is coming; reports say that these meteors willcrash into earth and destroy anything they hit. Anxious for her safety, shevows to find her way to a safe location (one that is never destroyed by ameteor) . She is currently grazing at the origin in the coordinate plane andwants to move to a new, safer location while avoiding being destroyed bymeteors along her way.

The reports say that M meteors (1 ≤ M ≤ 50,000) will strike, with meteor i will striking point (XiYi) (0 ≤ Xi ≤ 300; 0 ≤ Yi ≤ 300) at time Ti (0 ≤ Ti  ≤1,000). Each meteor destroys the point that it strikes and also the fourrectilinearly adjacent lattice points.

Bessie leaves the origin attime 0 and can travel in the first quadrant and parallel to the axes at therate of one distance unit per second to any of the (often 4) adjacentrectilinear points that are not yet destroyed by a meteor. She cannot belocated on a point at any time greater than or equal to the time it is destroyed).

Determine the minimum timeit takes Bessie to get to a safe place.

 

输入

Line 1: A single integer: M
Lines 2..M+1: Line i+1 contains three space-separated integers: Xi,Yi, and Ti

输出

Line 1: The minimum time it takes Bessie to get to a safe place or-1 if it is impossible.

样例输入

4
0 0 2
2 1 2
1 1 2
0 3 5

样例输出

5

来源

USACO 2008 February Silver

------------------------------------------------------------

思路

就是普通的不带权最短路BFS问题的变形。如果到达某点的时间小于陨石坠落到这点的时间,则可以过去;如果走到某一点永远不受陨石影响,则BFS返回。

关键是这题有好几个坑点,是看了POJ的discuss才明白的,估计要是考试做的话肯定想不到:

1. 可以t=0的时候就被陨石直接砸死,也有可能(0,0)永远不会被陨石波及,不用跑就安全了

2. 因为陨石有波及范围,所以同一个点可能被陨石影响几次,要取最早影响的那个时间

------------------------------------------------------------

代码

#include
#include
#include
#include
using namespace std;

const int BOUND = 405;
int mat[BOUND][BOUND] = {};

struct node {
	int x,y,t;

	node(void){}
	node(int xx, int yy, int tt): x(xx), y(yy), t(tt) {}
};

int bfs()
{
	int x,y,t;
	node nd(0,0,0), nd1;
	if (mat[nd.x][nd.y] >= 0 && mat[nd.x][nd.y] <= nd.t)
	{
		return -1;
	}
	queue q;
	q.push(nd);
	mat[0][0] = -2;											// -2表示bfs已经访问过了															
	while (!q.empty())
	{
		nd = q.front();
		q.pop();
		x = nd.x;
		y = nd.y;
		t = nd.t;
		if (x>0 && mat[x-1][y] != -2)
		{
			if (mat[x-1][y]==-1)
			{
				return t+1;
			}
			else if ( mat[x-1][y]>t+1 )
			{
				nd1.x = x-1;
				nd1.y = y;
				nd1.t = t+1;
				q.push(nd1);
				mat[x-1][y] = -2;
			}
		}
		if (xt+1 )
			{
				nd1.x = x+1;
				nd1.y = y;
				nd1.t = t+1;
				q.push(nd1);
				mat[x+1][y] = -2;
			}
		}
		if (y>0 && mat[x][y-1] != -2)
		{
			if (mat[x][y-1]==-1)
			{
				return t+1;
			}
			else if ( mat[x][y-1]>t+1 )
			{
				nd1.x = x;
				nd1.y = y-1;
				nd1.t = t+1;
				q.push(nd1);
				mat[x][y-1] = -2;
			}
		}
		if (yt+1 )
			{
				nd1.x = x;
				nd1.y = y+1;
				nd1.t = t+1;
				q.push(nd1);
				mat[x][y+1] = -2;
			}
		}
	}
	return -1;
}


int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin ("F.txt");
	int m,i,j,x,y,t;
	for (i=0; i> m;
	for (i=0; i> x >> y >> t;
		// 注意, 一个点可能被陨石砸中两次,取时间短的那次
		if (x>0 && (mat[x-1][y]==-1 || t < mat[x-1][y]))
		{
			mat[x-1][y] = t;
		}
		if (x0 && (mat[x][y-1]==-1 || t < mat[x][y-1]))
		{
			mat[x][y-1] = t;
		}
		if (y0 && (mat[x-1][y]==-1 || t < mat[x-1][y]))
		{
			mat[x-1][y] = t;
		}
		if (x0 && (mat[x][y-1]==-1 || t < mat[x][y-1]))
		{
			mat[x][y-1] = t;
		}
		if (y


你可能感兴趣的:(百练OJ/poj)