BZOJ 3677: [Apio2014] Lianzhu line tree DP

He fell to the nature of the analysis .... (also carefully read the title)

After carefully reading the title, we found that the red edge can connect a communication block and a leaf node (or two leaf nodes).

Then, if a legal state, if and only if a certain point in the root of all the edges are shaped such as blue son [x] -> x-> fa [x]

Then because of this nature, we can be a tree-DP.

Make $ 1 $ root, $ f [x] $ represent $ x $ is the maximum value when the blue side of the midpoint to $ x $ is the root of the subtree, $ g [x] $ represents the maximum value at the time is not a midpoint.

Then, when the root is not a $ 1 $, by changing the way the transfer to the root DP, it requires a minimum recording / transfer along with the next smallest value.

#include <cstdio>  
#include <string>
#include <cstring>
#include <algorithm>  
#define N 200007 
#define inf 1000000000 
using namespace std;    
void setIO(string s) 
{
    string in=s+".in"; 
    string out=s+".out"; 
    freopen(in.c_str(),"r",stdin); 
    // freopen(out.c_str(),"w",stdout); 
} 
int edges, n years;  
int f[N],g[N],hd[N],to[N<<1],nex[N<<1],val[N<<1],f1[N],f2[N];      
void add(int u,int v,int c) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
}
void dfs(int u,int ff) 
{   
    g [u] = 0, f [u] = - inf;  
    f1 [u] = f2 [u] = - inf;  
    for(int i=hd[u];i;i=nex[i]) 
    {
        int v=to[i]; 
        if(v==ff) continue;   
        dfs (v, u); 
        g[u]+=max(g[v],f[v]+val[i]);                    
    }    
    for(int i=hd[u];i;i=nex[i]) 
    {
        int v=to[i]; 
        if(v==ff) continue;         
        f[u]=max(f[u],g[u]-max(g[v],f[v]+val[i])+g[v]+val[i]);   
        int tmp=g[v]+val[i]-max(g[v],f[v]+val[i]);    
        if(tmp>f1[u]) f2[u]=f1[u],f1[u]=tmp;        
        else if(tmp>f2[u]) f2[u]=tmp;      
    }
}
void dfs2(int u,int ff) 
{  
    years = max (years g [u]);   
    for(int i=hd[u];i;i=nex[i]) 
    {
        int v=to[i];   
        if(v==ff) continue;     
        int gu=g[u]-max(g[v],g[v]+f1[v]+val[i]),fu;    
        if(f1[u]==g[v]+val[i]-max(g[v],g[v]+f1[v]+val[i])) fu=f2[u];     
        else fu=f1[u];   
        g[v]+=max(gu,gu+fu+val[i]);       
        fu = gu + val [i] -max (gu, gu + fu + val [i]);      
        if(fu>f1[v]) f2[v]=f1[v],f1[v]=fu;   
        else if(fu>f2[v]) f2[v]=fu; 
        dfs2 (v, u);   
    }
}
int main () 
{ 
    // setIO("input");  
    int i,j,x,y,z; 
    scanf("%d",&n);  
    for(i=1;i<n;++i) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);   
    years = inf; 
    dfs(1,0);   
    dfs2(1,0); 
    printf("%d\n",ans); 
    return 0; 
}

  

Guess you like

Origin www.cnblogs.com/guangheli/p/12131872.html