P4438 [HNOI/AHOI2018]道路

辣稽题目 毁我青春 耗我钱财。

\(f[x][i][j]\)为从1号点走到x点经过i条公路j条铁路,子树的最小代价。

\(f[leaf][i][j]=(A+i)(B+j)C\)

\(f[x][i][j]=min(f[ls][i+1][j]+f[rs][i][j],f[ls][i][j]+f[rs][i][j+1])\)

没了。

// luogu-judger-enable-o2
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
    rg int x=0,f=1;rg char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int maxn=40010;
int n,S[maxn],T[maxn];
int A[maxn],B[maxn],C[maxn],dp[maxn];
ll f[maxn][42][42];
il vd dfs(int x){
    if(x>=n){
        for(rg int i=0;i<=dp[x];++i)
            for(rg int j=0;j<=dp[x];++j)
                f[x][i][j]=1ll*(A[x]+i)*(B[x]+j)*C[x];
        return;
    }
    dp[S[x]]=dp[T[x]]=dp[x]+1;
    dfs(S[x]),dfs(T[x]);
    for(rg int i=0;i<=dp[x];++i)
        for(rg int j=0;j<=dp[x];++j)
            f[x][i][j]=std::min(f[S[x]][i][j]+f[T[x]][i][j+1],f[S[x]][i+1][j]+f[T[x]][i][j]);
}
int main(){
#ifdef xzz
    freopen("4438.in","r",stdin);
    freopen("4438.out","w",stdout);
#endif
    n=gi();
    for(rg int i=1;i<n;++i){
        S[i]=gi();if(S[i]<0)S[i]=-S[i]+n-1;
        T[i]=gi();if(T[i]<0)T[i]=-T[i]+n-1;
    }
    for(rg int i=n;i<n<<1;++i)A[i]=gi(),B[i]=gi(),C[i]=gi();
    dfs(1);
    printf("%lld\n",f[1][0][0]);
    return 0;
}
posted @ 2018-04-16 07:56  菜狗xzz  阅读(829)  评论(2编辑  收藏  举报