zoukankan      html  css  js  c++  java
  • loj 2759「JOI 2014 Final」飞天鼠

    loj

    这题有在一棵树上上升或者下降的操作,稍加分析后可以发现上升操作如果不是一定要做(指高度不足以到下一棵树或者是最后到达(n))就不做,下降操作也是如果不是一定要做(指到达下一棵树时高度过高)就不做,因为如果提前做了,可能会导致后面要浪费一些步数使得移动合法.然后这个移动过程就会分成两段,先是一直移动或者下降,不用上升,然后会每次上升再移动,一直到终点

    先看前一段的移动,如果移动的时候正好能移到下一棵树就直接移,如果移的时候高度过高就往下移一点直到能正好移动到下一棵树上.这里对每个点记(di_x)表示从起点到这里用了多久.注意我们还需要知道在某个树上所在的高度,由于这一部分没有上升操作,并且每过一个单位时间会下降1,所以在某点高度为(X-di_x).然后这个(di_x)应当记的是最短用时,因为用时越短,在的位置也越高,然后对后续转移也越有利,至于有可能要强制往下移,那只要在该移的时候向下移动就行,用时短一定不必用时长劣

    还有一种情况,是移到下一棵树会移到(<0)的高度,这时候我们就要往上移,移到能飞到下一棵树的位置,然后往下一棵树移.移到下一棵树后高度会变为0,这时候对于任何移动,我们都是先往上移(t_i(t_ile H_x)),然后飞到下一棵树,所以用时都是(2t_i).那么上面两种情况就可以分别用(dij)来转移了.注意如果在第一种移动过程中移到了(n),那么就可以更新答案了,所以最终答案为(min()这种情况的贡献(,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
    ",ans<(1ll<<50)?ans:-1);
    	return 0; 
    }
    
  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/smyjr/p/11618543.html
Copyright © 2011-2022 走看看