test190720 libreoj539 "LibreOJ NOIP Round # 1" travel route

https://loj.ac/problem/539

Fill hole ......

First, like $ f_ {i, j, k} $ $ I $ denotes the point, and the remaining $ J $ $ k $ element units oil, can travel the maximum distance

But in fact we found, $ f_ {i, j, k} $ either from $ f_ {s, j, k + 1} $ transferred from, or from $ f_ {i, k-p_i, min (c_i, C)} $ transferred over, then the last one-dimensional it becomes a bit redundant l

So consider $ f_ {i, j} $ $ I $ denotes the point, and the remaining $ J $ membered Save refueling added $ I $ points, the maximum distance able to walk, next refueling node metastasis enumerated i.e. can

Pretreatment of the greatest contribution to $ mx_ {i, j} $ I $ $ represents come from $ J $, after no more than $ $ C_i edges, can produce

Multiplication method with a similar optimization floyd +

#pragma GCC optmize(2)
#include<bits/stdc++.h>
using namespace std;
const int N=105,inf=1e9;
int n,m,C;
int p[N],c[N];
int f[N][N*N],g[N][N][20],mx[N][N],t[N][N];
void cmax(int x,int &y) {x>y?y=x:1;}
int rd()
{
    char ch='!'; int res=0;
    while(ch<'0' || ch>'9') ch=getchar();
    while(ch>='0' && ch<='9') res=res*10+ch-'0',ch=getchar();
    return res;
}
int main()
{
    freopen("trip.in","r",stdin); freopen("trip.out","w",stdout);
    int T;
    n=rd(),m=rd(),C=rd(),T=rd();
    for(int i=1;i<=n;++i)
    {
        p[i]=rd(),c[i]=rd();
        c[i]>C?c[i]=C:1;
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        {
            mx[i][j]=t[i][j]=-inf;
            for(int k=0;k<=16;++k) g[i][j][k]=i==j?0:-inf;    
        }
    for(int i=1;i<=m;++i)
    {
        int u,v,w;
        u=rd(),v=rd(),w=rd();
        cmax(w,g[u][v][0]);
    }
    for(int i=1;i<=16;++i)
        for(int j=1;j<=n;++j)
            for(int k=1;k<=n;++k)
                for(int l=1;l<=n;++l)
                    cmax(g[j][l][i-1]+g[l][k][i-1],g[j][k][i]);
    for(int i=1;i<=n;++i)
    {
        mx[i][i]=0;
        for(int cnt=16;cnt>=0;--cnt)
        if(c[i]>>cnt&1)
        {
            for(int j=1;j<=n;++j)
                for(int k=1;k<=n;++k)
                    cmax(mx[i][k]+g[k][j][cnt],t[i][j]);
            for(int j=1;j<=n;++j) mx[i][j]=t[i][j];
        }
    }
    for(int j=0;j<=n*n;++j)
        for(int i=1;i<=n;++i)
        {
            if(j<p[i]) continue;
            for(int k=1;k<=n;++k)
                cmax(f[k][j-p[i]]+mx[i][k],f[i][j]);
        }
    while(T--)
    {
        int s,q,d;
        //scanf("%d%d%d",&s,&q,&d);
        s=rd(),q=rd(),d=rd();
        int ans=lower_bound(f[s]+1,f[s]+q+1,d)-f[s];
        if(f[s][q]<d) puts("-1");
        else printf("%d\n",q-ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/w19567/p/11319736.html