P1122

最大子树和

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;
}
上一篇:3D Math Keynote 2


下一篇:树形DP——洛谷 P1122