题目链接:
题意:
给你一棵树,树上每一个点有一个权值,现在让你选两个点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 #include2 #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 -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 }