• 「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
    ",sum[n]+val[n]-H[n]);
    	return 0;
    }
    
  • 相关阅读:
    Linux recordmydesktop
    linux music play
    linux config NDK
    linux install wireshark
    Linux config cocos
    45 线程池都有哪些状态?
    44 创建线程池有哪几种方式?
    final 不能修饰抽象类和接口
    43 线程的 run() 和 start() 有什么区别?
    42 notify()和 notifyAll()有什么区别?
  • 原文地址:https://www.cnblogs.com/klauralee/p/11305457.html
Copyright © 2020-2023  润新知