Codeforces 627(DIV。3)F.MaximumホワイトサブツリーツリーDP

最初の質問塗りつぶしAKは、最終的には緑のフィールドがあります

このFのタイトル、DPは木学習に専念し2日間
、ほぼ日常的に感じ、特に困難な問題をしませんでしたが、さらにいくつかのより深い感動を行います

各トラックは、一般に、各ブロックの通信ポイントを見つけることが、黒または白点であることが、この手段ので、この通信ブロック番号におけるホワイトポイント - ブラックドットの最大数

真実を伝えるためには、それにはほとんど変化したテンプレートDPツリーです

双方向側にスターを付けるには元チェーン店は、再度慎重に、ダブルスペースを開くことを忘れないでください。私が知っているどのように聞かないでください。
コード:

#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