最大子树和
1.题目大意:
给出一棵树,求点权和最大的连通分量。
2.解题思路:
很显然是基础的树上DP问题。
跑dfs时套方程就好了。
3.方程:
我们用dp[i]
表示以i
为根的子树中点权和最大的一棵子树,用a[i]
表示点权。
dp[i]有两个选择:1.不剪断子树2.剪断子树。
如果u
是当前点,v
是下一个点,那么不难推出动态转移方程:dp[u]=max(dp[u],dp[u]+dp[v]);
4.代码:
#include<iostream>
#include<vector>
using namespace std;
vector<int> g[16005]; //只会用vector...
int n,dp[16005],a[16005];
void dfs(int u,int fa){
dp[u]=a[u]; //初始值
for(int i=0;i<(int)g[u].size();i++){
int v=g[u][i];
if(v!=fa){
dfs(v,u);
dp[u]=max(dp[u],dp[u]+dp[v]); //方程
}
}
}
int main(){
int x,y,ans=-0x7fffffff; //2147483647
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
cin>>x>>y;
g[x].push_back(y); //双向边
g[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=n;i++) ans=max(ans,dp[i]); //取最大值
cout<<ans<<endl;
return 0;
}