NOI 2019 D1T1 回家路线
题目大意:现在有 \(n\) 个车站,\(m\) 个车次,第 \(i\) 个车次会在 \(p\) 时刻到达 \(x\) 站点然后出发去 \(y\) 站点,并在 \(q\) 时刻抵达。有一个人从 \(1\) 号车站出发前往 \(n\) 号车站,每在一个车站等待 \(t\) 时间他的烦躁值就增加 \(At^2+Bt+C\) 。求到达 \(n\) 号车站最小的烦躁值。
数据范围:\(2\leq n\leq 10^5,1\leq m\leq 2\times 10^5,0\leq A\leq 10,0\leq B,C\leq 10^6,1\leq x_i,y_i,\leq n,0\leq p_i,q_i\leq 10^3\)
求最短路,使用 Dijkstra ,\(nm\) 的空间刚好开下。
斜率优化做法待写。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
template<class T>void read(T &x){
x=0; char c=getchar();
while(c<'0'||'9'<c)c=getchar();
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
const int N=100009;
const int M=1009;
int n,m,A,B,C,ans=0x7f7f7f7f;
struct edge{
int y,s,q;
}e[N<<1];
vector<int>head[N];
struct node{int x,t;};
int sum[N][M];
bool vis[N][M];
int cl(int t){return A*t*t+B*t+C;}
void bfs(){
#define ei head[x][i]
#define lev e[ei].s
#define arv e[ei].q
memset(sum,0x7f,sizeof(sum)); sum[1][0]=0;
queue<node>q;
node now; int x,y,t,tot;
q.push((node){1,0});
while(!q.empty()){
now=q.front(); q.pop();
x=now.x; t=now.t; vis[x][t]=0;
tot=head[x].size();
for(int i=0;i<tot;i++){
if(lev<t)continue;
if(sum[y=e[ei].y][arv]>sum[x][t]+cl(lev-t)){
sum[y][arv]=sum[x][t]+cl(lev-t);
if(!vis[y][arv]){
vis[y][arv]=1;
q.push((node){y,arv});
}
}
}
}
for(int i=1;i<=m;i++)if(e[i].y==n)ans=min(ans,sum[n][e[i].q]+e[i].q);
printf("%d",ans);
}
int main(){
//freopen("road.in","r",stdin);
//
read(n); read(m); read(A); read(B); read(C);
int x,y,s,q;
for(int i=1;i<=m;i++){
read(x); read(y); read(s); read(q);
e[i]=(edge){y,s,q};
head[x].push_back(i);
}
bfs();
//
//
return 0;
}