[HNOI / AHOI2018] road

Topic Link

 

analysis:

  This is in fact given a binary tree, each non-leaf node choose a son, then for each leaf node, its contribution is saying is that there are several nodes as the left / right son is not selected related to the root chain, the minimum required contributions and.

  Consider the tree $ DP $, but this contribution is a product, not convenient to directly split and merge do routine sub-tree from the bottom up.

  Observation Data range: size of the tree. 4 $ \. 4 Times 10 ^ $ , $ 40 $ depth. Found for each leaf, then the information can be kept down on top of the enumeration; non-leaf nodes are enumerated top information, discuss two cases.

  Provided $ f [u] [i] [j] $ represents: For the subtree $ U $, it is to the root strands has $ I $ a is not selected from the left child, $ J $ a selected right son, and the contribution of the sub-tree. Then $$ f [u] [i] [j] = min \ {f [ls] [i] [j] + f [rs] [i] [j + 1], f [ls] [i + 1] [j] + f [rs] [i] [j] \} $$

  Problem solution and discussion area where it seems that this title card space, then we can $ DFS $ properties, set $ f [d] [i] [j] [0/1] $ denotes the $ d $ layer, left / right son answers. successfully passed.

 

Implementation (100):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define IL inline
#define RG register
#define _1 first
#define _2 second
using namespace std;
typedef long long LL;
const int N=2e4;
const int M=40;

    int n,cit[N+3],vil[N+3];
    
struct Node{
    bool iscity;
    LL a,b,c;
    int s[2];
    
}a[N*2+3];
    int top;
    
IL int pickcity(int i){
    if(cit[i]==-1)
        return cit[i]=++top;
    return cit[i];
}

    LL f[M+3][M+3][M+3][2];

void dfs(int d,int t,int x,int rd,int ri){
    if(a[x].iscity){
        for(int i=0;i<2;i++)
            dfs(d+1,i,a[x].s[i],rd+(int)(i==0),ri+(int)(i==1));
        
        for(int i=0;i<=rd;i++)
            for(int j=0;j<=ri;j++)
                f[d][i][j][t]=min(f[d+1][i][j][0]+f[d+1][i][j+1][1]
                                 ,f[d+1][i+1][j][0]+f[d+1][i][j][1]);
        
    }
    else {
        for(int i=0;i<=rd;i++)
            for(int j=0;j<=ri;j++)
                f[d][i][j][t]=a[x].c*(a[x].a+i)*(a[x].b+j);
        
    }
    
}

int main(){
    scanf("%d",&n);
    top=-1;
    memset(cit,-1,sizeof cit);
    for(int i=1;i<n;i++){
        int k=pickcity(i);
        a[k].iscity=true;
        a[k].s[0]=a[k].s[1]=-1;
        
        int s[2],t;
        scanf("%d%d",&s[0],&s[1]);
        for(int j=0;j<2;j++)
        if(s[j]>0){
            t=pickcity(s[j]);
            a[t].iscity=true;
            a[k].s[j]=t;
            
        }
        else {
            t=++top;
            a[t].iscity=false;
            vil[-s[j]]=t;
            a[k].s[j]=t;
            
        }
        
    }
    
    for(int i=1;i<=n;i++)
        scanf("%lld%lld%lld",&a[vil[i]].a,&a[vil[i]].b,&a[vil[i]].c);
    
    dfs(1,0,0,0,0);
    
    printf("%lld",f[1][0][0][0]);

    return 0;

}
View Code

 

summary:

  The data range selected convenient flexible algorithm.

  When writing the title took some time to set up a node, a little Shousheng.

Guess you like

Origin www.cnblogs.com/Hansue/p/12104308.html