[Explanations] LOJ2759. "JOI 2014 Final" sugar glider (shortest)
Consider the final answer of the constitution, it must be increased from some of the many flight + + constitute some of the decline.
Due to a rise or fall at any price to pay is the same, so:
For up operation, as long as you do not need legal assurance in front of the flight rising. If and only if I did not fly past the rise.
For lowering operation, as long as I do not go beyond the target point you do not need to fall. If and only if I would cross the target point was dropped.
That is, the rise and fall operations are not required to manually make decisions, a more optimal solution does not exist so that such solution by a rise or fall in advance so that the time taken to shorten. Because it is assumed there is a "better solution", may be constructed out of the same set of optimal solutions to meet the above two principles by minimizing delay up operation.
So for each point, record a \ (Height \) indicates the current height and \ (dis \) represents the time it takes to direct Dijkstra.
Analyze complexity, whatever the cost is positive, so the same is \ (O (n \ log m ) \)
When read the way to delete illegal side ...
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e5+5;
const ll inf=1e18;
typedef pair<ll,int> P;
typedef priority_queue<P,vector<P>,greater<P> > Qp;
Qp q;
ll d[maxn];
int Height[maxn];
pair<int,pair<int,int> > last[maxn];
vector< pair<int,int> > e[maxn];
int h[maxn];
int n,m,X;
inline void add(const int&fr,const int&to,const int&w){
e[fr].push_back({to,w});
}
inline bool dij(){
Qp().swap(q);
for(int t=1;t<=n;++t) d[t]=inf,Height[t]=0;
d[1]=0; Height[1]=X; q.push({0,1});
while(q.size()){
auto now=q.top();
int Cur=now.second,H=Height[Cur];
q.pop();
if(now.first>d[Cur]) continue;
for(auto t:e[Cur]){
int to=t.first;
ll len=t.second;
if(H-len>h[to]){
ll g=H-h[to]+d[Cur];
if(d[to]>g){
d[to]=g;
Height[to]=h[to];
q.push({d[to],to});
}
continue;
}
if(H-len<0){
ll g=d[Cur]+len-H+len;
if(d[to]>g){
d[to]=g;
Height[to]=0;
q.push({d[to],to});
}
continue;
}
if(d[to]>d[Cur]+len){
d[to]=d[Cur]+len;
Height[to]=H-len;
q.push({d[to],to});
continue;
}
}
}
if(d[n]==inf) return 0;
return 1;
}
int main(){
n=qr(); m=qr(); X=qr();
for(int t=1;t<=n;++t) h[t]=qr();
for(int t=1;t<=m;++t){
int t1=qr(),t2=qr(),t3=qr();
if(t3<=h[t1]) add(t1,t2,t3);
if(t3<=h[t2]) add(t2,t1,t3);
}
if(!dij()) return puts("-1"),0;
ll ans=d[n]+h[n]-Height[n];
printf("%lld\n",ans);
return 0;
}