牛客练习赛78 C CCA的子树
https://ac.nowcoder.com/acm/contest/11168/C
类似于dp求树的直径
在以x为根的子树内,求x的子树里的最大和次大的x的子树的子树和,要求最大和次大不能在x的同一个子节点里。
每次以子节点的最大子树和更新x的最大子树和
最后再用x的子树和更新x的最大子树和
#include<cstdio> #include<algorithm> using namespace std; #define N 200001 typedef long long LL; int a[N]; int front[N],to[N<<1],nxt[N<<1],tot; LL sum[N],mx[N]; LL ans=-1e18; void add(int u,int v) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; } void dfs(int x,int y) { sum[x]=a[x]; int t; LL maxn=-1e18; for(int i=front[x];i;i=nxt[i]) { t=to[i]; if(t==y) continue; dfs(t,x); sum[x]+=sum[t]; ans=max(ans,mx[t]+maxn); maxn=max(maxn,mx[t]); } mx[x]=max(maxn,sum[x]); } int main() { int n,u,v; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<n;++i) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } sum[0]=-1e18; dfs(1,0); if(ans==-1e18) printf("Error"); else printf("%lld",ans); }