[Luogu P5468] NOI 2019 D1T1 回家路线

Posted on 2020-06-01 21:34  opethrax  阅读(228)  评论(0编辑  收藏  举报

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;
}