Codeforces Round #384 (Div. 2) D. Chloe and pleasant prizes(树形DP)

题目链接: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\n",ans);
37     else puts("Impossible");
38     return 0; 
39 }
View Code

 

posted @ 2016-12-15 14:06  bin_gege  阅读(173)  评论(0编辑  收藏  举报