[Explanations] LOJ2759. "JOI 2014 Final" sugar glider (shortest)

[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;
}

Guess you like

Origin www.cnblogs.com/winlere/p/11617368.html