题目大意: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]); } } } }
原文地址:http://blog.csdn.net/jiangyuze831/article/details/40046191