思路,先预处理出每个板子能跳到的第一块板子(e[i].way=1意思是朝左边跳,e[i].way=2意思是朝右边跳)然后把能跳到的最近的板子按照左右跳建图,然后在用最短路 只能过少量点,其它基本都是tle
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 1010
int n,beg,ed;
struct A{
int d,l,r,h;
}a[maxn*2],b[maxn*2];
struct E{
int to,nxt,way;
}e[maxn*2];
bool cmp(A a,A b){
return a.h<b.h;
}
int cnt,head[maxn],dis[maxn];
void add(int a,int b,int w){
e[++cnt].to=b;
e[cnt].nxt=head[a];
head[a]=cnt;
e[cnt].way=w;
}
struct node{
int u,w,mid;
friend bool operator <(node a,node b){
return a.w<b.w;
}
}tmp;
priority_queue<node>q;
void dijk(){
for(int i=1;i<=n;i++){
dis[i]=897987987;
}
dis[beg]=0;
tmp.u=beg,tmp.w=0,tmp.mid=b[beg].l;//mid是指跳到下一块板子的落点
q.push(tmp);
while(!q.empty()){
tmp=q.top();
q.pop();
int v=tmp.u;
for(int i=head[v];i;i=e[i].nxt){
if(e[i].way==2&&dis[e[i].to]>(long long)b[v].r-tmp.mid+b[v].h-b[e[i].to].h+dis[v]){
dis[e[i].to]=b[v].r-tmp.mid+b[v].h-b[e[i].to].h+dis[v];
tmp.mid=b[v].r;
}
if(e[i].way==1&&dis[e[i].to]>(long long)tmp.mid-b[v].l+b[v].h-b[e[i].to].h+dis[v]){
dis[e[i].to]=tmp.mid-b[v].l+b[v].h-b[e[i].to].h+dis[v];
tmp.mid=b[v].l;
}
tmp.w=dis[e[i].to],tmp.u=b[e[i].to].d;
q.push(tmp);
}
}
}
int main(){
cin>>n;
cin>>beg>>ed;
for(int i=1;i<=n;i++){
cin>>a[i].l>>a[i].r>>a[i].h;
a[i].d=i;
}
memcpy(b,a,sizeof(a));
sort(a+1,a+1+n,cmp);
int t;
for(int i=n;i>=1;i--){
int flag1=0,flag2=0;
t=1;
while(i-t>=1){
if(a[i].r>=a[i-t].l&&a[i].r<=a[i-t].r&&!flag1&&a[i-t].d!=0){
add(a[i].d,a[i-t].d,2);
flag1=1;
}
if(a[i].l>=a[i-t].l&&a[i].l<=a[i-t].r&&!flag2&&a[i-t].d!=0){
add(a[i].d,a[i-t].d,1);
flag2=1;
}
t++;
}
}
dijk();
if(dis[ed]==897987987)cout<<-1;
else cout<<dis[ed];
return 0;
}