LOJ 3156: "NOI2019" route home

Topic Portal: LOJ # 3156 .

Description meaning of the questions:

There is a \ (n-\) points \ (m \) edges of the directed graph, there are two side weights \ (P_i \) and \ (Q_I \) ( \ (P_i <Q_I \) ) indicates if \ (p_i \) time on this side of the starting point, then \ (q_i \) time to reach the end of this edge.

You need to plan a route, so that from the beginning \ (1 \) starting dot along this route to reach the end \ (n \) dot.

Suppose the route passing sequentially side is \ (\ {A_1, A_2, \ ldots, a_k \} \) , it is necessary to ensure that \ (I-Q_ {A_. 1} {} \ {a_i Le P_} \) .
The expense of this route is \ (\ displaystyle q_ {a_k} + \ sum_ {i = 2} ^ {k} f (p_ {a_i} -q_ {a_ {i-1}}) + f (p_ {a_1 }) \) , where \ (F (X) = \ mathrm {A} + X ^ 2 \ mathrm {B} + X \ mathrm {C} \) .

You need to make the cost of your planned route of the minimum output of this minimum price.

answer:

Transfer between the cost of a quadratic function, it will be apparent slope DP optimization model.

Consider \ (\ mathrm {f} [ i] \) represented through the first \ (I \) edges after \ (\ F SUM ({a_j P_ A_ {} {J--q_. 1}}) \) , of Jane formula:

\[\begin{aligned}\mathrm{f}[i]&=\min_{y_j=x_i,q_j\le p_i}\{\mathrm{f}[j]+\mathrm{A}(p_i-q_j)^2+\mathrm{B}(p_i-q_j)+\mathrm{C}\}\\&=\min_{y_j=x_i,q_j\le p_i}\{\mathrm{f}[j]+\mathrm{A}p_i^2-2\mathrm{A}p_iq_j+\mathrm{A}q_j^2+\mathrm{B}p_i-\mathrm{B}q_j+\mathrm{C}\}\\&=\min_{y_j=x_i,q_j\le p_i}\{\mathrm{f}[j]+\mathrm{A}q_j^2-\mathrm{B}q_j-2\mathrm{A}p_iq_j\}+\mathrm{A}p_i^2+\mathrm{B}p_i+\mathrm{C}\end{aligned}\]

Expression where the slope is evident, \ (X \) coordinates \ (Q_I \) , \ (Y \) coordinates \ (\ mathrm {f} [ i] + \ mathrm {A} q_i ^ 2- \ mathrm {B} Q_I \) , so \ (\ mathrm {D} _i = \ mathrm {A} P_i ^ 2 + \ mathrm {B} P_i + \ mathrm {C} \) ,
then \ (\ displaystyle \ mathrm {f } [I] = \ mathrm _i} + {D \ {y_j = min_ x_i, Q_j \ Le P_i} \ {2-y_j \ mathrm p_ix_j {A} \} \) .

Investigation two legal transition point \ (J \) and \ (K \) ( \ (x_j <x_k \) ), the transition point \ (J \) than the transition point \ (K \) preferably if and only if:

\[\begin{aligned}y_j-2\mathrm{A}p_ix_j&<y_k-2\mathrm{A}p_ix_k\\2\mathrm{A}p_i(x_k-x_j)&<y_k-y_j\\\frac{y_k-y_j}{x_k-x_j}&>2\mathrm{A}p_i\end{aligned}\]

Because the number is greater than the number range, so maintaining the convex hull.

Note that, for convenience, according to the update order \ (P_i \) from small to large, so that the right slope is increasing, but it does not have updated immediately added convex hull, but should wait until the turn of the corresponding \ (P_i \) when then add.

The following is the code, the time complexity is \ (\ mathcal {O} (n-m + + \ Q max) \) :

#include <cstdio>
#include <algorithm>
#include <vector>

typedef double db;
const int MN = 100005, MM = 200005, MQ = 1005;

int N, M, _A, _B, _C, Ans = 0x3f3f3f3f;
int d[MN], eu[MM], ev[MM], ep[MM], eq[MM];
std::vector<int> vp[MQ], vq[MQ];
int X[MM], Y[MM], f[MM];
int _stk[MM], *stk[MN], _l[MN], _r[MN];

inline db Slope(int i, int j) {
    if (X[i] == X[j]) return Y[i] == Y[j] ? 0 : Y[i] < Y[j] ? 1e99 : -1e99;
    return (db)(Y[j] - Y[i]) / (X[j] - X[i]);
}

int main() {
    freopen("route.in", "r", stdin);
    freopen("route.out", "w", stdout);
    scanf("%d%d%d%d%d", &N, &M, &_A, &_B, &_C);
    ev[0] = 1, vq[0].push_back(0), ++d[1];
    for (int i = 1; i <= M; ++i) {
        scanf("%d%d%d%d", &eu[i], &ev[i], &ep[i], &eq[i]);
        vp[ep[i]].push_back(i);
        vq[eq[i]].push_back(i);
        ++d[ev[i]];
    }
    stk[0] = _stk;
    for (int i = 1; i <= N; ++i) stk[i] = stk[i - 1] + d[i - 1], _l[i] = 1;
    for (int t = 0; t <= 1000; ++t) {
        for (auto i : vq[t]) {
            int u = ev[i], *st = stk[u], l = _l[u], &r = _r[u];
            while (l < r && Slope(st[r - 1], st[r]) > Slope(st[r], i)) --r;
            st[++r] = i;
            if (u == N && Ans > f[i] + eq[i]) Ans = f[i] + eq[i];
        }
        for (auto i : vp[t]) {
            int u = eu[i], *st = stk[u], &l = _l[u], r = _r[u];
            while (l < r && Slope(st[l], st[l + 1]) < 2 * _A * t) ++l;
            if (l <= r) f[i] = Y[st[l]] - 2 * _A * t * X[st[l]] + _A * t * t + _B * t + _C;
            else f[i] = 0x3f3f3f3f;
            X[i] = eq[i], Y[i] = f[i] + _A * eq[i] * eq[i] - _B * eq[i];
        }
    }
    printf("%d\n", Ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/PinkRabbit/p/NOI2019D1T1.html