首页 > 代码库 > POJ 1661 Help Jimmy 最短路

POJ 1661 Help Jimmy 最短路

题目大意:POJ少有的中文题,自己看吧,题意挺简单的。


思路:这本是一道DP的题,被我用最短路水过去了,没想到还0ms。

建图的思路比较简单,就是实现起来比较费劲。把每个东西按高度排序,从上到下n^2的枚举左右端点,然后满足条件的连边,边权为高度差+水平距离差。

然后跑SPFA就行了。注意一下Jimmy直接能跳到地面上的情况,这wa了一次。


CODE:


#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;

struct Complex{
	int l,r;
	bool _l,_r;
	int height;

	Complex(int _,int __,int ___):l(_),r(__),height(___) {}
	Complex() {}
	bool operator <(const Complex &a)const {
		return height > a.height;
	}
	void Read() {
		scanf("%d%d%d",&l,&r,&height);
		_l = _r = false;
	}
}point[MAX];

int cases;
int points,x,y,limit;
int head[MAX],total;
int next[MAX],aim[MAX],length[MAX];

int f[MAX];
bool v[MAX];

inline void Initialize();
inline void Add(int x,int y,int len);
inline void SPFA(int start);

int main()
{
	for(cin >> cases;cases; --cases) {
		scanf("%d%d%d%d",&points,&x,&y,&limit);
		Initialize();
		for(int i = 1;i <= points; ++i)
			point[i].Read();
		point[++points] = Complex(-20000,20000,0);
		point[0].height = y;
		sort(point + 1,point + points + 1);
		for(int i = 1;i <= points; ++i)
			if(x >= point[i].l && x <= point[i].r)
				if(y - point[i].height <= limit) {
					Add(1,i << 1,y - point[i].height + x - point[i].l);
					Add(1,i << 1|1,y - point[i].height + point[i].r - x);
					break;
				}
		for(int i = 1;i <= points; ++i)
			for(int j = 1;j < i; ++j) {
				if(point[j].height - point[i].height > limit)	continue;
				if(!point[j]._l && point[j].l >= point[i].l && point[j].l <= point[i].r) {
					Add(j << 1,i << 1,point[j].height - point[i].height + point[j].l - point[i].l);
					Add(j << 1,i << 1|1,point[j].height - point[i].height + point[i].r - point[j].l);
					point[j]._l = true;
				}
				if(!point[j]._r && point[j].r >= point[i].l && point[j].r <= point[i].r) {
					Add(j << 1|1,i << 1,point[j].height - point[i].height + point[j].r - point[i].l);
					Add(j << 1|1,i << 1|1,point[j].height - point[i].height + point[i].r - point[j].r);
					point[j]._r = true;
				}
			}
		SPFA(1);
		printf("%d\n",f[points << 1]);
	}
	return 0;
}

inline void Initialize()
{
	total = 0;
	memset(head,0,sizeof(head));
}

inline void Add(int x,int y,int len)
{
	next[++total] = head[x];
	aim[total] = y;
	if(y == (points << 1) || y == (points << 1|1))
		length[total] = point[x >> 1].height;
	else	length[total] = len;
	head[x] = total;
}

inline void SPFA(int start)
{
	static queue<int> q;
	while(!q.empty())	q.pop();
	memset(f,0x3f,sizeof(f));
	f[start] = 0;
	q.push(start);
	while(!q.empty()) {
		int x = q.front(); q.pop();
		v[x] = false;
		for(int i = head[x];i;i = next[i]) 
			if(f[aim[i]] > f[x] + length[i]) {
				f[aim[i]] = f[x] + length[i];
				if(!v[aim[i]]) {
					v[aim[i]] = true;
					q.push(aim[i]);
				}
			}
	}
}


POJ 1661 Help Jimmy 最短路