[NOI2019] home route

Keywords: PHP

LOJ3156

Don't put in the question, put in the data range.

Seeing \ (n < = 2000, m < = 4000 \) and thinking of direct \ (dfs \) in the end, I actually passed the first \ (4 \) sample and the last \ (2s \). Later, I wrote \ (5 \) score of \ (A=B=0 \), and I knew whether it was wrong or handed in the following code. (LOJ data should be official data) score \ (70 \).

In the evening, I went to LOJ for a test, and found that if I ran directly, I had a score of \ (80 \), and then I read an excellent article in \ (AC \) record, which was changed to the back.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<queue>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int N=100005;
const int M=200005;

struct Edge{
    int v,s,t,nxt;
}e[M];
int first[N],Ecnt=0;
inline void Add_edge(int u,int v,int s,int t){
    e[++Ecnt]=(Edge){v,s,t,first[u]};
    first[u]=Ecnt;
}

int n, m, A, B, C;

inline LL calc(int x){
    return 1ll * A * x * x + 1ll * B * x + C;
}

namespace baoli{
    LL ans = INF;
    inline void dfs(int u, int time, LL cost){
        if(u == n){
            ans = min(ans, cost + time);
        }
        for(int i = first[u]; i; i = e[i].nxt){
            int v = e[i].v, s = e[i].s, t = e[i].t;
            if(s < time) continue;
            dfs(v, t, cost + calc(s - time));
        }
    }
    inline void main(){
        dfs(1, 0, 0);
        printf("%lld\n", ans);
        exit(0);
    }
};

namespace Subtask1{ // A == 0 && B == 0
    int dis[N], time[N];
    queue <int> q;
    LL ans = INF;
    inline void Return(LL ans){
        printf("%lld\n", ans);
        exit(0);
    }
    inline void main(){
        q.push(1);
        memset(dis, 0x3f, sizeof dis);
        dis[1] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(int i = first[u]; i; i = e[i].nxt){
                int v = e[i].v;
                if(time[u] > e[i].s) continue;
                if(dis[u] + 1 < dis[v]){
                    dis[v] = dis[u] + 1;
                    time[v] = e[i].t;
                    q.push(v);

                }
                if(v == n) ans = min(ans, 1ll * (dis[u] + 1 + 1) * C + e[i].t);
            }
        }
        Return(ans);
        assert(false);
    }
    /*inline void main(){
        q.push((Node){1, 0, 0});
        while(!q.empty()){
            int u = q.front().x, d = q.front().dis, t = q.front().time; q.pop();
            for(int i = first[u]; i; i = e[i].nxt){
                int v = e[i].v;
                if(e[i].t < t) continue;
                if(
            }
        }
    }*/
};

int main(){
#ifndef file
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
#endif
    n = read(), m = read(), A = read(), B = read(), C = read();
    for(register int i = 1; i <= m; ++i){
        register int x = read(), y = read(), p = read(), q = read();
        Add_edge(x, y, p, q);
    }
    if(n <= 2000 && m <= 4000) 
        baoli::main();
    if(A == 0 && B == 0) Subtask1::main();
}

An AC code on LOJ

I didn't notice the time \ (Q < = 1000 \), so \ (O(nq)=O(1e8) \) should be able to get stuck?

Direct \ (dp \) someone got it 95 points . sort the trains by time, and then update them in turn, so that \ (1e8 \) is not satisfied with the running, and it will pass directly. You can use \ (vector \) to save the status.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const LL INF=1e18+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int N = 1e5 + 5;
const int M = 2e5 + 5;

struct Node{
    int x, y, p, q;
}a[M];
inline bool cmp1(Node a, Node b){
    if(a.p == b.p) return a.q < b.q;
    return a.p < b.p;
}

vector <LL> f[N];
vector <int> t[N];
int n, m, A, B, C;

inline LL calc(int x){
    return 1ll * A * x * x + 1ll * B * x + C;
}

int main(){
#ifndef file
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
#endif
    n = read(), m = read(), A = read(), B = read(), C = read();
    for(int i = 1; i <= m; ++i){
        a[i].x = read(), a[i].y = read(), a[i].p = read(), a[i].q = read();
    }
    sort(a + 1, a + m + 1, cmp1);

    f[1].push_back(0), t[1].push_back(0);
    for(int i = 1; i <= m; ++i){
        int x = a[i].x, y = a[i].y, p = a[i].p, q = a[i].q;
        int tt = -1;
        for(int j = 0; j < t[y].size(); ++j)
            if(t[y][j] == q) {tt = j; break;}
        for(int j = 0; j < f[x].size(); ++j){
            if(t[x][j] > p) continue;
            int len = p - t[x][j];
            if(tt == -1){
                f[y].push_back(f[x][j] + calc(len));
                t[y].push_back(q);
                tt = f[y].size() - 1;
            }
            else if(f[x][j] + calc(len) < f[y][tt]){
                f[y][tt] = f[x][j] + calc(len);
            }
        }
    }
    LL ans = INF;
    for(int i = 0; i < f[n].size(); ++i)
        ans = min(ans, f[n][i] + t[n][i]);
    printf("%lld\n", ans);
}

Posted by Roo on Wed, 23 Oct 2019 15:26:29 -0700