codeforces743D 【DFS】
题意:
给你一棵以1为root的根,然后让你求两棵不相交子树的最大和;
思路:
DFS,主要就是你一定得使两棵子树不相交;
对于一个顶点u,维护以u为根的最大子树和。
①:包含u,即所有的结点和。
②:不包含,在子树内找一个最大子树。
每次对于一个根搞搞就好了,维护一下答案;
这个DFS真的赞。。一开始wa4还是那个没有保证子树不相交,后来RE5 and WA5 DFS的函数int应该写LL...(菜啊!
大家都说是树型DP...在弱弱眼里就是个DFS啊ヽ(*。>Д<)o゜......
给你一棵以1为root的根,然后让你求两棵不相交子树的最大和;
思路:
DFS,主要就是你一定得使两棵子树不相交;
对于一个顶点u,维护以u为根的最大子树和。
①:包含u,即所有的结点和。
②:不包含,在子树内找一个最大子树。
每次对于一个根搞搞就好了,维护一下答案;
这个DFS真的赞。。一开始wa4还是那个没有保证子树不相交,后来RE5 and WA5 DFS的函数int应该写LL...(菜啊!
大家都说是树型DP...在弱弱眼里就是个DFS啊ヽ(*。>Д<)o゜......
//赛后qqq神的一句话总结得真好:子树 sum 和 子树内的子树最大 sum
#include<bits/stdc++.h> using namespace std; typedef __int64 LL; const LL INF=-1e18; const int N=2e5+10; int n; LL val[N]; struct asd { int to; int next; }; asd q[2*N]; int head[2*N],tol; void add(int u,int v) { q[tol].to=v; q[tol].next=head[u]; head[u]=tol++; } LL ans; bool vis[N]; int DFS(int u,LL &W) { vis[u]=1; LL sum=val[u]; LL ans1,ans2; ans1=ans2=INF; for(int i=head[u];i!=-1;i=q[i].next) { if(vis[q[i].to]) continue; LL tmp; sum+=DFS(q[i].to,tmp); if(tmp>ans1) { ans2=ans1; ans1=tmp; } else if(tmp>ans2) ans2=tmp; } if(ans2!=INF) ans=max(ans,ans1+ans2); W=max(sum,ans1); return sum; } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%I64d",&val[i]); int u,v; tol=0; memset(head,-1,sizeof(head)); for(int i=1; i<n; i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } ans=INF; memset(vis,0,sizeof(vis)); LL tmp; DFS(1,tmp); if(ans!=INF) printf("%I64d\n",ans); else puts("Impossible"); return 0; }