codeforces-743D-树形dp

来源:互联网 发布:网络兼职项目申请表 编辑:程序博客网 时间:2024/05/21 06:20

题目大意:给定一棵树,有两个人分别取一个顶点并且它的所有子树,并且这两个人取得部分不可以有重复,问两人取得权值总和最大是多少;

题目解析:先dfs一次另val[i]表示取第i个顶点和它的子树总和是多少,再dfs一次令dp[i]表示在他所包含的子树中,最大值是多少;第三次dfs更新答案ans,dfs到一个点如果有多个儿子的话,就取出他们之中最大的两个dp加起来更新ans;

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<vector>#define inf 2000000010using namespace std;typedef long long ll;const int maxn=200010;vector<int>vec[maxn];ll dp[maxn],val[maxn];void dfs(int root,int fa){for(int i=0;i<vec[root].size();i++){int v=vec[root][i];if(fa==v)continue;dfs(v,root);val[root]+=val[v];}dp[root]=val[root];}void dfs1(int root,int fa){for(int i=0;i<vec[root].size();i++){int v=vec[root][i];if(fa==v)continue;dfs1(v,root);dp[root]=max(dp[root],dp[v]);}}ll ans;void dfs2(int root,int fa){ll t1,t2;t1=-inf;t2=-inf;for(int i=0;i<vec[root].size();i++){if(fa==vec[root][i])continue;dfs2(vec[root][i],root);ll t=dp[vec[root][i]];if(t>=t1){t2=t1;t1=t;continue;}if(t>t2){t2=t;}}if(t1!=-inf&&t2!=-inf)ans=max(ans,t1+t2);}int main(){ll n;memset(dp,0,sizeof(dp));ans=-inf;scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&val[i]);for(int i=1;i<=n-1;i++){int u,v;scanf("%d%d",&u,&v);vec[u].push_back(v);vec[v].push_back(u);}dfs(1,-1);//cout<<1<<endl;dfs1(1,-1);//cout<<1<<endl;dfs2(1,-1);if(ans==-inf)printf("Impossible\n");else printf("%lld\n",ans);return 0;}



0 0
原创粉丝点击