[NOI2019]回家路線


[NOI2019]回家路線

題目大意:

\(n\)個站點,\(m\)趟車,每趟車在\(p_i\)時從\(x_i\)出發,\(q_i\)時到達\(y_i\)

若小貓共乘坐了\(k\)班列車,依次乘坐的列車編號可用序列\(s_{1\sim k}\)表示。該方案被稱作一條可行的回家路線,當且僅當它滿足下列兩個條件:

  1. \(x_{s_1}=1,y_{s_k}=n\)
  2. 對於所有\(j(1\le j<k)\)滿足\(y_{s_j}=x_{s_{j+1}}\)\(q_{s_j}\le p_{s_{j+1}}\)

對於該回家路線,小貓得到的煩躁值將為:

\[q_{s_k}+(A\cdot p_{s_1}^2+B\cdot p_{s_1}+C)+\sum_{j=1}^{k-1}(A(p_{s_{j+1}}-q_{s_j})^2+B(p_{s_{j+1}}+q_{s_j})+C) \]

小貓想讓自己的煩躁值盡量小,請你幫它求出所有可行的回家路線中,能得到的最小的煩躁值。題目保證至少存在一條可行的回家路線。

\(n\le 10^5,m\le2\times10^5,1\le p_i<q_i\le 1000\)

思路:

將所有車按照\(p_i\)排序,枚舉每趟車,枚舉到達\(p_i\)的時間。

\(f[i][j]+i\)表示時間\(j\)到達\(i\)車站最小煩躁值。

時間復雜度\(\mathcal O(m\cdot q)\)

源代碼:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=1e5+1,M=2e5+1,T=1e3+1;
int n,m,A,B,C,f[N][T];
struct Edge {
	int u,v,p,q;
	bool operator < (const Edge &rhs) const {
		return p<rhs.p;
	}
};
Edge e[M];
inline int calc(const int &x) {
	return A*x*x+B*x+C;
}
inline void upd(int &a,const int &b) {
	a=std::min(a,b);
}
int main() {
	freopen("route.in","r",stdin);
	freopen("route.out","w",stdout);
	n=getint(),m=getint();
	A=getint(),B=getint(),C=getint();
	for(register int i=1;i<=m;i++) {
		const int u=getint(),v=getint(),p=getint(),q=getint();
		e[i]=(Edge){u,v,p,q};
	}
	for(register int i=1;i<=n;i++) {
		std::fill(&f[i][0],&f[i][T],INT_MAX);
	}
	f[1][0]=0;
	std::sort(&e[1],&e[m]+1);
	for(register int i=1;i<=m;i++) {
		for(register int j=0;j<=e[i].p;j++) {
			if(f[e[i].u][j]==INT_MAX) continue;
			upd(f[e[i].v][e[i].q],f[e[i].u][j]+calc(e[i].p-j));
		}
	}
	int ans=INT_MAX;
	for(register int i=0;i<T;i++) {
		if(f[n][i]!=INT_MAX) upd(ans,f[n][i]+i);
	}
	printf("%d\n",ans);
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM