loj 2759 "JOI 2014 Final" sugar glider

serious

This entitled the rise or fall of a tree operation, after a little analysis can be found if it is not up operation must be done (refers to the height is not enough to reach the next tree or the last \ (the n-\) ) do not down operation also must do if it is not (refers to the height is too high to reach a tree) would not do, because if you do ahead of time, may lead to waste some back a few steps so that the movement of legitimate then this process will move divided into two sections, first has to move or fall, not rise, then rise again to move every time, all the way to the end

Look at the front section of the movement, if you move just in time to be able to move directly to the next tree, if the height is too high when the shift down a little until you can go out just to move on to the next tree. Here each dot notation \ (di_x \) expressed from the beginning to here with how long. Note that we also need to know the height of a tree where, due to the operation of this section does not rise, and every once in a unit of time will be decreased by 1, so in a point height \ (X--di_x \) . then the \ (di_x \) should be recorded is shortest, because shorter duration, at a position higher, then the subsequent transfer of the more advantageous, as it is possible to force move down, as long as it moves down the line at the time of the shift, is not necessary when using certain short duration inferior

In another case, a tree will be moved to the next \ (<0 \) in height, this time we will move up, move to the next position might fly into trees, then down a tree shift. after moving to the next tree height becomes 0, this time for any movement, we are the first to move up \ (t_i (t_i \ Le H_X) \) , and then flew to a tree, so when use is \ (2t_i \) . so you can use the above two cases were \ (dij \) be transferred. Note If you move in the first movement in the \ (the n-\) , then you can update the answer , so the final answer is \ (min (\) contribution to this situation \ (, dis_n + H_n) \ )

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db long double

using namespace std;
const int N=1e5+10;
int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
};
int n,m,X,h[N],e[N*3][3];
struct node
{
    LL x,d;
    bool operator < (const node &bb) const {return d>bb.d;}
};
priority_queue<node> q,qq;
int to[N<<4],nt[N<<4],w[N<<4],hd[N],tot=1;
void add(int x,int y,int z)
{
    ++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
}
LL di[N],ans=1ll<<50;

int main()
{
    n=rd(),m=rd(),X=rd();
    for(int i=1;i<=n;++i) h[i]=rd();
    for(int i=1;i<=m;++i)
        for(int j=0;j<=2;++j)
            e[i][j]=rd();
    for(int i=1;i<=m;++i)
    {
        int x=e[i][0],y=e[i][1],z=e[i][2];
        add(x,y,z),add(y,x,z);
    }
    memset(di,0x3f3f3f,sizeof(LL)*(n+1));
    qq.push((node){1,di[1]=0});
    LL he=X;
    while(!qq.empty())
    {
        int x=qq.top().x;
        LL d=qq.top().d;
        qq.pop();
        if(d>di[x]) continue;
        if(x==n) ans=min(ans,di[x]+h[n]-(he-di[x]));
        for(int i=hd[x];i;i=nt[i])
        {
            int y=to[i];
            if(he-di[x]-w[i]<=0&&w[i]<=h[x]) q.push((node){y,di[x]+w[i]-(he-di[x]-w[i])});
            else
            {
                LL dt=max(0ll,he-di[x]-w[i]-h[y]);
                if(di[y]>di[x]+w[i]+dt&&di[x]+w[i]+dt<=he) qq.push((node){y,di[y]=di[x]+w[i]+dt});
            }
        }
    }
    memset(hd,0,sizeof(int)*(n+1)),tot=1;
    for(int i=1;i<=m;++i)
    {
        int x=e[i][0],y=e[i][1],z=e[i][2];
        if(h[x]>=z) add(x,y,z<<1);
        if(h[y]>=z) add(y,x,z<<1);
    }
    memset(di,0x3f3f3f,sizeof(LL)*(n+1));
    while(!q.empty())
    {
        int x=q.top().x;
        LL d=q.top().d;
        q.pop();
        if(d>di[x]) continue;
        if(d<di[x]) di[x]=d;
        for(int i=hd[x];i;i=nt[i])
        {
            int y=to[i];
            if(di[y]>di[x]+w[i])
                q.push((node){y,di[y]=di[x]+w[i]});
        }
    }
    ans=min(ans,di[n]+h[n]);
    printf("%lld\n",ans<(1ll<<50)?ans:-1);
    return 0; 
}

Guess you like

Origin www.cnblogs.com/smyjr/p/11618543.html