题目链接:D. Chloe and pleasant prizes
题意:
给你一棵树,树上每一个点有一个权值,现在让你选两个点a,b,使得a不是b的子节点且b不是a的子节点,问最大的ans。
ans的定义是sum(a)+sum(b)(sum(a)以a为根的所以子节点权值和(包括a),b同理)。
题解:
dp[i]记录以i这个节点为根的最大子节点的sum,f[i]记录sum[i],然后dfs下去,中途更新答案即可。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef long long ll; 5 6 const int N=2e5+7; 7 int a[N],n,g[N],nxt[N*2],v[N*2],ed; 8 ll dp[N],f[N],ans,inf=1ll<<61; 9 10 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 11 inline void up(ll &a,ll b){if(a<b)a=b;} 12 13 void dfs(int u,int fa) 14 { 15 f[u]=a[u],dp[u]=-inf; 16 for(int i=g[u];i;i=nxt[i])if(v[i]!=fa) 17 { 18 dfs(v[i],u); 19 if(dp[u]>-inf)up(ans,dp[u]+dp[v[i]]); 20 up(dp[u],dp[v[i]]),f[u]+=f[v[i]]; 21 } 22 up(dp[u],f[u]); 23 } 24 25 int main() 26 { 27 scanf("%d",&n); 28 F(i,1,n)scanf("%d",a+i); 29 F(i,1,n-1) 30 { 31 int x,y; 32 scanf("%d%d",&x,&y); 33 adg(x,y),adg(y,x); 34 } 35 ans=-inf,dfs(1,0); 36 if(ans>-inf)printf("%lld ",ans); 37 else puts("Impossible"); 38 return 0; 39 }