给定一张 n 个点 m 条边的无重边无自环的有向图,你要从 1 号点到 n 号点去。
如果你在 t 时刻之后到达 n 号点,你要交 x 元的罚款。
每条边从 ai 到 bi,走过它需要花费 ci 元,多次走过同一条边需要多次花费。
走过每条边所需的时间是随机的,对于 k∈[1,t],105pi,k 表示走过第 i 条边需要时间 k 的概率。因此如果多次走过同一条边,所需的时间也可能不同。
你希望花费尽可能少的钱(花费与罚款之和)到达 n 号点,因此每到达一个点,你可能会更改原有的计划。
求在最优决策下,你期望花费的钱数。
n≤50,m≤100,t≤2×104,x,ci≤106,∑k=1tpi,k=105,答案精度误差 ≤10−6。
首先设 dpi,j 表示在 j 时刻开始,从 i 走到 n 的最小花费,那么有:
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧dpn,i=0dpn,i=xdpu,i=u – j -> vmincj+k=1∑t105pj,kdpv,i+kdpu,i=dist(u,n)+xi≤ti>tu=n,i≤tu=n,i>t
其中 dist(x,y) 表示从 x 到 y 的最小花费(路程上的,不算罚款),我们最后需要 dp1,0。
由于这不一定是 DAG 而且 dijkstra 不好写所以需要 spfa,然而暴力跑 spfa 是 O(nmt2) 的,显然不够优。
容易发现,令人讨厌的转移部分显然是 k=1∑t105pj,kdpv,i+k,考虑优化这一部分。
令 p’j,t−k=105pj,k,那么原式可化为:
k=1∑tpj,t−k′dpv,i+k
容易发现这是一个卷积的形式,下标和恒为 t−k+i+k=i+t,那么式子就变成了:
(pj′∗dpv)i+t
所以优化后的转移为:
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧dpn,i=0dpn,i=xdpu,i=u – j -> vmincj+(pj′∗dpv)i+tdpu,i=dist(u,n)+xi≤ti>tu=n,i≤tu=n,i>t
跑 spfa 的话时间复杂度为 O(nmtlogt),但是跑不满,而且有 8S,所以足够通过此题。
spfa 在反向图上跑即可,相当于倒着转移吧。