[洛谷P1122][题解]最大子树和

这是一道还算简单的树型dp。

转移方程:f[i]=max(f[j],0)

其中i为任意非叶节点,j为i的一棵子树,而每棵子树都有选或不选两种选择

具体看代码:

#include<bits/stdc++.h>
using namespace std;
int n;

struct Edge {
    int to,next;
}e[35005];
int head[16005],cnt;
inline void adde(int u,int v){
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}

int f[16005],val[16005],fa[16005];
/*
f表示最大字树和 
val表示每个节点的值
fa表示祖先 
*/

//找祖宗 
void dfsf(int k,int f){
    fa[k]=f;
    for(int i=head[k];i;i=e[i].next){
        int v=e[i].to;
        if(v!=f){
            dfsf(v,k);
        }
    }
}

int maxn=-0x3f3f3f3f;

//dp 
void dfs(int k){
    f[k]=val[k];
    for(int i=head[k];i;i=e[i].next){
        int v=e[i].to;
        if(v!=fa[k]){
            dfs(v);
            f[k]+=max(f[v],0);
            /*
            两种情况:
            选或不选k的子树
            */ 
        }
    }
    maxn=max(maxn,f[k]);
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>n;
    
    for(int i=1;i<=n;i++){
        cin>>val[i];
    }
    
    for(int i=1;i<n;i++){
        int a,b;
        cin>>a>>b;
        adde(a,b);
        adde(b,a);
    }
    
    int rt=1;
    dfsf(rt,0);
    dfs(rt);
    
    cout<<maxn<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/juruoajh/p/11793913.html