Codeforces 627 (Div. 3) F.Maximum White Subtree 树形DP

第一次补题AK,终于有场绿色的了

为了这个F题,这两天专门学习了树形DP
没做什么特别难的题,感觉套路都差不多,再多做几道加深加深印象

这道大体意思是每个点有黑或白色,为每个点找一个连通块,使这个连通块内 白色点的数目-黑色点的数目 最大

说实话就是树形DP模板稍一改就可以了

链式前向星存双向边,记得开双倍空间,小心re。。。别问我怎么知道的。。。。
代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int MaxSize = 200005;

struct node
{
    int to,next;
}q[3*MaxSize];
int a[MaxSize],head[MaxSize],cnt=1,d[MaxSize];

void add(int a,int b)
{
    q[cnt].to=a;
    q[cnt].next=head[b];
    head[b]=cnt;
    cnt++;
}

void dfs(int u,int f)
{
    for(int i=head[u];i!=-1;i=q[i].next)
    {
        int v=q[i].to;
        if(v==f)
        {continue;}
        dfs(v,u);
        d[u]=max(d[u],d[v]+d[u]);
    }
    return ;
}
void dfs2(int u,int f)
{
    if(u!=f)
    {
        if(d[u]>=0)
        {d[u]=max(d[u],d[f]);}
        else
        {d[u]=max(d[u],d[u]+d[f]);}
    }
    for(int i=head[u];i!=-1;i=q[i].next)
    {
        int v=q[i].to;
        if(v==f)
        {continue;}
        dfs2(q[i].to,u);
    }
    return;
}

int main()
{
    memset(head,-1,sizeof(head));
    int n,x,y;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==0)d[i]=-1;
        else{d[i]=1;}
    }
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d %d",&x,&y);
        add(x,y);add(y,x);
    }
    dfs(1,1);
    dfs2(1,1);
    for(int i=1;i<=n;i++)
    {
        cout<<d[i]<<" ";
    }
    cout<<endl;
    return 0;
}

发布了36 篇原创文章 · 获赞 4 · 访问量 1380

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/104929412