[ZJOI2006] 三色二叉树

Posted ssf-xiaoban

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZJOI2006] 三色二叉树相关的知识,希望对你有一定的参考价值。

树形dp

题目传送门

题目大意:给定一棵二叉树,将节点染成红、绿,蓝三种颜色,求绿色节点个数的最大值和最小值。

这题建树十分恶心,需要一些技巧:

观察输入数列及题面,可以知道任意一个节点的左子树一定在右子树的左边,且紧邻右子树

这样就可以跑一个dfs,先搜左子树,记录左子树节点个数ln,则数组下标ln+1的数便是右子树的根,再搜右子树,记录节点个数rn,则ln+rn+1就是下一个要搜的点

 

对于染色,每个节点可以分为两种情况:染绿色和不染绿色

我们可以令f[i][0/1]表示以节点i为根的子树中,当i不染绿色/染绿色时,绿色节点个数的最大值,ff[i][0/1]同理,求最小值

则当i有一个儿子时,f[i][1]=f[ls[i]][0]+1

则当i有两个儿子时,f[i][0]=max(f[ls[i]][0]+f[rs[i]][1],f[rs[i]][0]+f[ls[i]][1])      f[i][1]=f[ls[i]][0]+f[rs[i]][0]+1

求最小值同理

代码:

#include<bits/stdc++.h>
using namespace std;
char c[1000005];
int p[1000005];
int n;
int lst;
int s[1000005];
int f[1000005][2];
int ff[1000005][2];
int ls[1000005],rs[1000005];
int build(int cur)

    if(p[cur]==0) return 1;
    else if(p[cur]==1)
    
        ls[cur]=cur+1;
        int t=build(cur+1);
        return t+1;
    
    else
    
        ls[cur]=cur+1;
        int t=build(cur+1);
        rs[cur]=cur+t+1;
        int tt=build(cur+t+1);
        return t+tt+1;
    

void dfs(int i)

    if(ls[i]!=0) dfs(ls[i]);
    if(rs[i]!=0) dfs(rs[i]);
    if(s[i]==1)
    
        f[i][1]=f[ls[i]][0]+1;
        ff[i][1]=ff[ls[i]][0]+1;
        f[i][0]=max(f[ls[i]][0],f[ls[i]][1]);
        ff[i][0]=min(ff[ls[i]][0],ff[ls[i]][1]);
    
    if(s[i]==2)
    
        f[i][1]=f[ls[i]][0]+f[rs[i]][0]+1;
        ff[i][1]=ff[ls[i]][0]+ff[rs[i]][0]+1;
        f[i][0]=max(f[ls[i]][0]+f[rs[i]][1],f[rs[i]][0]+f[ls[i]][1]);
        ff[i][0]=min(ff[ls[i]][0]+ff[rs[i]][1],ff[rs[i]][0]+ff[ls[i]][1]);
    

int main()

    cin>>(c+1);
    n=strlen(c+1);
    for(int i=1;i<=n;i++) p[i]=c[i]-0;
    build(1);
    for(int i=1;i<=n;i++)
    
        if(ls[i]&&rs[i]) s[i]=2;
        else if(!ls[i]&&!rs[i]) s[i]=0;
        else s[i]=1;
        if(s[i]==0) f[i][1]=ff[i][1]=1;
    
    dfs(1);
    //for(int i=1;i<=n;i++) cout<<i<<‘ ‘<<f[i][0]<<‘ ‘<<f[i][1]<<endl;
    cout<<max(f[1][0],f[1][1])<< <<min(ff[1][1],ff[1][0])<<endl;
    return 0;

谷歌输入法真™难用

 

以上是关于[ZJOI2006] 三色二叉树的主要内容,如果未能解决你的问题,请参考以下文章

ZJOI2006 三色二叉树

BZOJ-1864: [Zjoi2006]三色二叉树 (julao都说简单的树形DP)

bzoj1864: [Zjoi2006]三色二叉树(树形DP)

[ZJOI2006] 三色二叉树

ZJOI2006 三色二叉树

BZOJ_1864_[Zjoi2006]三色二叉树_树形DP