这是一道还算简单的树型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; }
原文:https://www.cnblogs.com/juruoajh/p/11793913.html