「JOI 2014 Final」飞天鼠

「JOI 2014 Final」飞天鼠

显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0。

到达一个点有两种情况:到达高度为0和不为0。

对于高度不为0的情况,显然花费的时间越少高度越高(每下降1m都要1单位时间),而必然高度越高越好,因此只需求花费的最少时间。

对于高度为0的情况,显然花费的时间越少越好。

高度不为0的情况比高度为0的情况要优越,而且事实上,高度不为0的情况花费必然会小于高度为0的情况。因此两种情况可以直接合并。

故可以直接dijkstra跑一遍。

复杂度\(o(mlog(m))\)。

#include<bits/stdc++.h>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
#define mem(a,b) memset(a,b,sizeof a )
using namespace std;
typedef long long ll;
char buf[15000000],*p1=buf,*p2=buf;
#define Getchar() p1==p2?EOF:*p1++
void in(int &r) {
    static char c;
    r=0;
    while(c=Getchar(),c<48);
    do r=(r<<1)+(r<<3)+(c^48);
    while(c=Getchar(),c>47);
}
const int mn=100005;
const int mm=300005;
int head[mn],ne[mm<<1],to[mm<<1],cost[mm<<1],cnt1;
#define link_edge(a,b,c) to[++cnt1]=b,ne[cnt1]=head[a],head[a]=cnt1,cost[cnt1]=c
#define travel(x) for(int q(head[x]);q;q=ne[q])
int val[mn];
int n,m;
ll sum[mn];
int H[mn];
bool mark[mn];
struct node {
    ll v;
    int id;
    bool operator <(const node &A)const {
        return v>A.v;
    }
};
priority_queue<node> qw;
void WA(int at) {
    
    rep(q,1,n)sum[q]=1e18;
    qw.push({0,1}),H[1]=at,sum[1]=0;
    ll v;
    while(!qw.empty()) {
        node now=qw.top();
        qw.pop();
        if(mark[now.id])continue;
        mark[now.id]=1;
        int h=H[now.id];
        travel(now.id) {
            if(h-cost[q]>val[to[q]]) {
                v=sum[now.id]+h-cost[q]-val[to[q]]+cost[q];
                if(sum[to[q]]>v) {
                    sum[to[q]]=v;
                    H[to[q]]=val[to[q]];
                    qw.push({sum[to[q]],to[q]});
                }
            } else if(h-cost[q]<0) {
                v=sum[now.id]+cost[q]-h+cost[q];
                if(sum[to[q]]>v) {
                    sum[to[q]]=v;
                    H[to[q]]=0;
                    qw.push({sum[to[q]],to[q]});
                }
            } else {
                if(sum[to[q]]>sum[now.id]+cost[q]) {
                    sum[to[q]]=sum[now.id]+cost[q];
                    H[to[q]]=h-cost[q];
                    qw.push({sum[to[q]],to[q]});
                }
            }
        }
    }
}
int main() {
    p2=buf+fread(buf,1,15000000,stdin);
    int at;
    in(n),in(m),in(at);
    rep(q,1,n)in(val[q]);
    int a,b,c;
    rep(q,1,m) {
        in(a),in(b),in(c);
        if(val[a]>=c)link_edge(a,b,c);
        if(val[b]>=c)link_edge(b,a,c);
    }
    WA(at);
    if(sum[n]==1e18)puts("-1");
    else printf("%lld\n",sum[n]+val[n]-H[n]);
    return 0;
}
上一篇:CVE-2014-6271——bash破壳漏洞复现


下一篇:【转帖】CentOS 7 修改时区