POJ 1661 Help Jimmy 최단거리
사고방식: 이 책은 DP의 문제인데 내가 가장 짧은 물로 지나갔는데 0ms가 될 줄은 몰랐다.
그림을 짓는 사고방식은 비교적 간단하지만 실현하기가 비교적 어렵다.모든 물건을 높이에 따라 순서를 정하고 위에서 아래로 n^2까지 좌우 단점을 매거한 다음에 조건을 만족시키는 연변은 고도차+수평거리차이다.
SPFA 뛰면 돼.Jimmy가 직접 지면으로 뛰어내릴 수 있는 상황을 주의해라. 이것은 한 번 흔들렸다.
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
",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]);
}
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.