P6302 回家路线
Mentos_Cola · · 题解
题意
给定
Solution
一开始我想以当前所在地点为状态来
那么设
至此我们以
把
但是我们还有两个限制,一个是
第一个好办,我们开
第二个则需要我们算出
这样为什么可行呢?在算
我看到上面的题解大多都使用了堆,带上了一个
代码:
#include<bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
const int M=1e6+10,inf=1e18,eps=1e-9;
int st[M],nd[M],p[M],q[M],x[M],y[M],h[M],t[M],dp[M];
vector<int>pos[M],ins[M],Q[M];
void read(int &x){
int f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x*=f;
}
int pf(int x){return x*x;}
double slope(int i,int j){
int xx=x[j]-x[i],yy=y[j]-y[i];
if(!xx){
if(yy>0)return inf;
return -inf;
}
return yy*1./xx;
}
signed main(){
int n,m,A,B,C,T=0,ans=inf;
read(n),read(m),read(A),read(B),read(C);
for(int i=1;i<=m;i++){
read(st[i]),read(nd[i]),read(p[i]),read(q[i]);
T=max(T,q[i]),pos[p[i]].push_back(i);
}
for(int i=1;i<=n;i++)h[i]=0,t[i]=-1;
for(int pi=0;pi<=T;pi++){
for(int id=0;id<ins[pi].size();id++){
int i=ins[pi][id],pp=nd[i];
while(h[pp]<t[pp]&&slope(Q[pp][t[pp]-1],Q[pp][t[pp]])>=slope(Q[pp][t[pp]-1],i))t[pp]--;
++t[pp];
if(t[pp]>=Q[pp].size())Q[pp].push_back(i);
else Q[pp][t[pp]]=i;
}
for(int id=0;id<pos[pi].size();id++){
int i=pos[pi][id],pp=st[i];double k=2.*A*pi;
while(h[pp]<t[pp]&&slope(Q[pp][h[pp]],Q[pp][h[pp]+1])<k)h[pp]++;
if(h[pp]>t[pp]&&st[i]!=1)continue;
int j;
if(st[i]==1&&h[pp]>t[pp])j=0;
else j=Q[pp][h[pp]];
dp[i]=dp[j]+A*pf(p[i]-q[j])+B*(p[i]-q[j])+C;
x[i]=q[i],y[i]=dp[i]+A*pf(q[i])-B*q[i];
ins[q[i]].push_back(i);
if(nd[i]==n)ans=min(ans,dp[i]+q[i]);
}
}
cout<<ans<<endl;
return 0;
}