Weight the Tree CodeForces - 1646D

http://codeforces.com/contest/1646/problem/D

Under the condition that "good" points cannot be adjacent to each other, the number of "good" points is maximized, typical tree DP.

Under the condition of maximizing the number of "good" points, the weight is minimized (the weight of non-"good" points is 1, and the weight of "good" points is the sum of the weights of adjacent points), which can also be processed according to tree DP.

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;

struct node
{
    int v,tp,next;
};

node edge[2*maxn];
int first[maxn],dp1[maxn][2],dp2[maxn][2],val[maxn];
int n,num,ans1,ans2;

void addedge(int u,int v)
{
    edge[num].v=v;
    edge[num].tp=-1;
    edge[num].next=first[u];
    first[u]=num++;
}

void dfsI(int cur,int fa)
{
    int i,v;
    dp1[cur][1]=1;
    dp2[cur][0]=1;
    for(i=first[cur];i!=-1;i=edge[i].next){
        v=edge[i].v;
        if(v!=fa){
            dfsI(v,cur);
            dp1[cur][1]+=dp1[v][0];
            dp2[cur][1]+=dp2[v][0]+1;
            if(dp1[v][0]>dp1[v][1]){
                dp1[cur][0]+=dp1[v][0];
                dp2[cur][0]+=dp2[v][0];
                edge[i].tp=0;
            }
            else if(dp1[v][0]<dp1[v][1]){
                dp1[cur][0]+=dp1[v][1];
                dp2[cur][0]+=dp2[v][1]+1;
                edge[i].tp=1;
            }
            else if(dp2[v][0]<dp2[v][1]+1){
                dp1[cur][0]+=dp1[v][0];
                dp2[cur][0]+=dp2[v][0];
                edge[i].tp=0;
            }
            else{
                dp1[cur][0]+=dp1[v][1];
                dp2[cur][0]+=dp2[v][1]+1;
                edge[i].tp=1;
            }
        }
    }
}

void dfsII(int cur,int fa,int tp)
{
    int i,v;
    if(tp==0){
        val[cur]=1;
    }
    for(i=first[cur];i!=-1;i=edge[i].next){
        v=edge[i].v;
        if(v!=fa){
            if(tp==0){
                dfsII(v,cur,edge[i].tp);
            }
            else{
                dfsII(v,cur,0);
            }
        }
    }
}

int main()
{
    int i,u,v;
    scanf("%d",&n);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=n-1;i++){
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    if(n==2){
        printf("2 2\n1 1\n");
    }
    else{
        dfsI(1,0);
        if(dp1[1][0]>dp1[1][1]){
            ans1=dp1[1][0],ans2=dp2[1][0];
            dfsII(1,0,0);
        }
        else if(dp1[1][0]<dp1[1][1]){
            ans1=dp1[1][1],ans2=dp2[1][1];
            dfsII(1,0,1);
        }
        else if(dp2[1][0]<dp2[1][1]){
            ans1=dp1[1][0],ans2=dp2[1][0];
            dfsII(1,0,0);
        }
        else{
            ans1=dp1[1][1],ans2=dp2[1][1];
            dfsII(1,0,1);
        }
        for(u=1;u<=n;u++){
            if(val[u]){
                continue;
            }
            for(i=first[u];i!=-1;i=edge[i].next){
                v=edge[i].v;
                val[u]+=val[v];
            }
        }
        printf("%d %d\n",ans1,ans2);
        for(i=1;i<=n;i++){
            printf("%d ",val[i]);
        }
        printf("\n");
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325447214&siteId=291194637