首页 > 其他 > 详细

Luogu P1122 最大子树和

时间:2019-08-19 21:35:24      阅读:125      评论:0      收藏:0      [点我收藏+]

题目链接

题目大意:给定一棵树,每个点带点权,请你求出点权和最大的联通块和是多少。

树形DP简单题

f[x]为以x为根的子树,含x的联通块点权最大和。对于每个v(v∈son(x)),只要f[v]不是负数就把v选上。

f[x]=∑max(f[son(x)],0)

#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read() {
    char ch;
    bool bj=0;
    while(!isdigit(ch=getchar()))
        bj|=(ch==-);
    int res=ch^(3<<4);
    while(isdigit(ch=getchar()))
        res=(res<<1)+(res<<3)+(ch^(3<<4));
    return bj?-res:res;
}
void printnum(int x) {
    if(x>9)printnum(x/10);
    putchar(x%10+0);
}
inline void print(int x,char ch) {
    if(x<0) {
        putchar(-);
        x=-x;
    }
    printnum(x);
    putchar(ch);
}
int f[16005],a[16005],h[16005];
struct Edge {
    int to,nxt;
} w[16005<<1];
int cnt,n;
inline void AddEdge(int x,int y) {
    w[++cnt].to=y;
    w[cnt].nxt=h[x];
    h[x]=cnt;
}
int ans=-0x3f3f3f3f;
void DFS(int x,int fa) {
    for(int i=h[x]; i; i=w[i].nxt) {
        int v=w[i].to;
        if(v==fa)continue;
        DFS(v,x);
        f[x]+=max(f[v],0);
    }
    f[x]+=a[x];
    ans=max(ans,f[x]);
}
signed main() {
    n=read();
    for(int i=1; i<=n; i++)a[i]=read();
    int x,y;
    for(int i=1; i<n; i++) {
        x=read();
        y=read();
        AddEdge(x,y);
        AddEdge(y,x);
    }
    DFS(1,0);
    print(ans,\n);
    return 0;
}

 

Luogu P1122 最大子树和

原文:https://www.cnblogs.com/soledadstar/p/11379698.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!