P5468 [NOI2019] route home

Portal

Look at the subject an optimized slope, then write for a long time not out of tune

The results have an error of $ dfs $ $ 95 $ points? Violence $ SPFA $ on $ AC $ up?

Talk about positive solutions:

Clearly optimization is the slope of the equation:

Not considered contribution $ q_ {s_k} $, the set $ f [i] $ $ I represents the current time is the minimum cost of $

Without considering the positional relationship with $ f [p_i] = f [q_j] + A (p_i-q_j) ^ 2 + B (p_i-q_j) + C $

Open to: $ f [p_i] = f [q_j] + Ap_i ^ 2-2Ap_iq_j + Aq_j ^ 2 + Bp_i-Bq_j + C $

Change places $ 2Ap_iq_j + f [p_i] -Ap_i ^ 2-Bp_i-C = f [q_j] + Aq_j ^ 2-Bq_j $

那么 $k=2Ap_i,x=q_j,b=f[p_i]-Ap_i^2-Bp_i-C,y=f[q_j]+Aq_j^2-Bq_j$

Obviously direct slope optimization

But the location and the time, may wish to train each time split into two $ p, q $ query and insert respectively, and then sorted by time Sign

So that each train departure time before it reaches the cars are finished processing, you can calculate the contribution directly at each train arrives, then insert new contributions convex hull

Because there are limitations position relationship, so open $ a $ Vector for each position corresponding to the convex hull maintenance position

Then is the specific implementation details of the ...

Maintenance found that the convex hull is inserted from the right, left pop-up, can be directly inserted with a $ vector $ a $ push \ _back, pop \ _back $

Left pop can maintain for each $ vector $ a variable $ pos $ express the left-most point of the current legal

Updates to the final answer can be sentenced especially when updating the array $ dp $

Then we should pay attention to various details of the problem (adjusted vomiting blood)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(x=='- ' ) F = - . 1 ; CH = getchar ();}
     the while (CH> = ' 0 ' && CH <= ' . 9 ' ) = {X (X << . 1 ) + (X << . 3 ) + (CH ^ 48 ); CH = getchar ();}
     return X * F; 
} 
const  int N = 4E5 + . 7 , INF = 2E9 + . 7 ;
 int n-, m, A, B, C, ANS = INF, POS [N], Val [ N]; // Val contribution of each train maintenance 
inline int Calc ( int T) { return a * T * T * T + B + C;}
 struct{Train // train 
    int X, Y, P, Q; 
} T [N]; 
struct DAT { // according to the schedule ordered 
    int Tim, type, id; // type judgment that the inserted or query, id is the train number 
    inline BOOL  operator <( const DAT & tmp) const {
         return Tim < tmp.tim; 
    } 
} D [N]; 
struct Datt { // the convex hull points 
    int Tim, RES; // time, the cost of which has been generated 
    inline int X-( ) { return Tim;} 
    inline int the Y () { return* A * Tim-RES-B * Tim Tim;} 
}; 
Vector <Datt> V [N]; // Vector Maintenance convex hull 
inline Cross LL (LL XA, XB LL, LL Ya, Yb LL) { return XA * XB * Ya-Yb;} // relationship between the cross product of a straight line is determined 
inline int the Y ( int P) { return Val [P] -A * T [P] .q * T [P] .qB * T [P ] .q;} 
inline void Push ( int P) // insert 
{
     int T = T [P] .y; IF (Val [P]> = INF) return ; // note judgment Laid 
    the while ( int (V [T ] .size ()) - POS [T]> = 2 )// remember -POS [T] 
    {
         int len = V [T] .size ();
         IF (Cross (T [P] .qV [T] [len 2 ] .X (), the Y (P) -V [T] [len 2 ] .Y (), V [T] [len . 1 ] .X () - V [T] [len 2 ] .X (), V [T] [len . 1 ] .Y () - V [T] [len 2 ] .Y ()) < 0 )
             BREAK ; 
        V [T] .pop_back (); // Vector function comes 
    } 
    V [T] .push_back ((Datt) T {[P] .q, Val [P]}); // Add 
}
 int main () 
{ 
    // The freopen ( "route.in", "R & lt", stdin);
     //freopen("route.out","w",stdout);
    n=read(),m=read(),A=read(),B=read(),C=read();
    int a,b,c,d,tot=0;
    for(int i=1;i<=m;i++)
    {
        a=read(),b=read(),c=read(),d=read();
        T[i]=(Train){a,b,c,d};
        D[++tot]=(dat){c,0,i}; D[++tot]=(dat){d,1,i};//把列车拆成两个点
    }
    sort(D+1,D+tot+1); V[1].push_back((datt){0,0 }); // remember the initial insertion point 
    Memset (val, 0x7F , the sizeof (val)); val [ 0 ] = 0 ; // note is val 0x7f, it will add a little burst int 
    for ( int I = . 1 ; I <= TOT; I ++ ) 
    { 
        int P = D [I] .id, T = T [P] .x;
         IF (D [I] .Type) {Push (P); Continue ;}
         the while ( int (V [T] .size ()) - POS [T]> . 1 .. && V [T] [POS [T]] + Calc RES (D [I] .tim-V [T] [POS [T]] Tim )> V = [T] [POS [T] + . 1 ] + Calc .res (D [I] .tim-V [T] [POS [T] + . 1  ] .tim))
            POS [T] ++ ;
         IF (POS [T] < int . (V [T] .size ())) Val [P] = V [T] [POS [T]] + Calc RES (D [I] V-.tim [T] [POS [T]] Tim);. // update Val 
        IF (T [P] .y == && n-Val [P] <INF) ANS = min (ANS, Val [P] + T [P] .q); // Note that some trains to sit on, while if val 0x7F, plus a value will explode 
    } 
    the printf ( " % D \ n- " , ANS);
     return  0 ; 
}

 Attach the way most violent mindless $ SPFA $:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(x=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=1e5+7,M=1007,INF=2e9+7;
struct Train{
    int x,y,p,q;
}T[N<<1];
struct dat{
    int pos,tim;
};
queue <dat> Q;
vector <int> V[N];
int n,m,A,B,C,ans=INF;
inline int clac(int t) { return A*t*t+B*t+C; }
int dis[N][M];
bool vis[N][M];
int main()
{
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
    n=read(),m=read(),A=read(),B=read(),C=read();
    int a,b,c,d;
    for(int i=1;i<=m;i++)
    {
        a=read(),b=read(),c=read(),d=read();
        T[i]=(Train){a,b,c,d};
        V[a].push_back(i);
    }
    memset(dis,0x7f,sizeof(dis));
    Q.push((dat){1,0}); vis[1][0]=1; dis[1][0]=0;
    while(!Q.empty())
    {
        dat x=Q.front(); Q.pop(); vis[x.pos][x.tim]=0;
        int len=V[x.pos].size();
        for(int i=0;i<len;i++)
        {
            int &p=V[x.pos][i]; if(x.tim>T[p].p) continue;
            int cst=clac(T[p].p-x.tim);
            if(dis[T[p].y][T[p].q]>dis[x.pos][x.tim]+cst)
            {
                dis[T[p].y][T[p].q]=dis[x.pos][x.tim]+cst;
                if(!vis[T[p].y][T[p].q]) Q.push((dat){T[p].y,T[p].q}),vis[T[p].y][T[p].q]=1;
            }
        }
    }
    for(int i=1;i<=m;i++) if(T[i].y==n) ans=min(ans,dis[n][T[i].q]+T[i].q);
    printf("%d\n",ans);
    return 0;
}
SPFA

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11208025.html