Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:

例如,下图所表示的二叉树可以用二叉树序列S=21200110来表示。

你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。

 Input

输入数据由多组数据组成。
每组数据仅有一行,不超过10000个字符,表示一个二叉树序列。

 Output

对于每组输入数据,输出仅一行包含两个整数,依次表示最多和最少有多少个点能够被染成绿色。

 Sample Input

1122002010

 Sample Output

5 2

 

 

 

【思路】先建树,然后进行树形DP;

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int inf=0x7777777;
const int colorn=3;
enum color{green, red, blue, none};//enum 枚举名{ 枚举值表 };在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
struct node
{
    node *left,*right;
    int maxg[colorn],ming[colorn];
    node()
    {
        left=right=NULL;
        memset(maxg,0,sizeof(int)*colorn);
        memset(ming,0,sizeof(int)*colorn);
    }
};
typedef node *T;//指针类型定义:T等价于node *定义,T tree声明等价于node *a声明;
const int N=10005;
char *build(T &tree,char *a)//建树
{
    if(a[0]=='0')
    {
        tree=new node();
        return a+1;
    }
    else if(a[0]=='1')
    {
        tree=new node();
        return build(tree->left,a+1);
    }
    else
    {
        tree=new node();
        char *pos=build(tree->left,a+1);
        return build(tree->right,pos);
    }
}
void TDP(T &tree)
{
    if(tree==NULL) return ;
    TDP(tree->left);
    TDP(tree->right);
    if(tree->left==NULL&&tree->right==NULL)
    {
        tree->maxg[green]=1;tree->maxg[red]=tree->maxg[blue]=0;

        tree->ming[green]=1;tree->ming[red]=tree->ming[blue]=0;
    }
    else if(tree->left!=NULL&&tree->right==NULL)
    {
        tree->maxg[green]=max(tree->left->maxg[red],tree->left->maxg[blue])+1;
        tree->maxg[red]=max(tree->left->maxg[blue],tree->left->maxg[green]);
        tree->maxg[blue]=max(tree->left->maxg[green],tree->left->maxg[red]);

        tree->ming[green]=min(tree->left->ming[red],tree->left->ming[blue])+1;
        tree->ming[red]=min(tree->left->ming[blue],tree->left->ming[green]);
        tree->ming[blue]=min(tree->left->ming[red],tree->left->ming[green]);
    }
    else if(tree->right!=NULL&&tree->left==NULL)
    {
        tree->maxg[green]=max(tree->right->maxg[red],tree->right->maxg[blue])+1;
        tree->maxg[red]=max(tree->right->maxg[blue],tree->right->maxg[green]);
        tree->maxg[blue]=max(tree->right->maxg[green],tree->right->maxg[red]);

        tree->ming[green]=min(tree->right->ming[red],tree->right->ming[blue])+1;
        tree->ming[red]=min(tree->right->ming[blue],tree->right->ming[green]);
        tree->ming[blue]=min(tree->right->ming[red],tree->right->ming[green]);
    }
    else
    {
        tree->maxg[green]=max(tree->right->maxg[red]+tree->left->maxg[blue],tree->right->maxg[blue]+tree->left->maxg[red])+1;
        tree->maxg[red]=max(tree->right->maxg[green]+tree->left->maxg[blue],tree->right->maxg[blue]+tree->left->maxg[green]);
        tree->maxg[blue]=max(tree->right->maxg[green]+tree->left->maxg[red],tree->right->maxg[red]+tree->left->maxg[green]);

        tree->ming[green]=min(tree->right->ming[red]+tree->left->ming[blue],tree->right->ming[blue]+tree->left->ming[red])+1;
        tree->ming[red]=max(tree->right->ming[green]+tree->left->ming[blue],tree->right->ming[blue]+tree->left->ming[green]);
        tree->ming[blue]=max(tree->right->ming[green]+tree->left->ming[red],tree->right->ming[red]+tree->left->ming[green]);

    }
}
void destroy(T &tree)
{
    if(tree==NULL) return ;
    destroy(tree->left);
    destroy(tree->right);
    delete tree;
}
int main()
{
    char a[N];
    while(~scanf("%s",a))
    {
        T tree=NULL;
        build(tree,a);

        TDP(tree);
        int maxx=-inf,minn=inf;
        for(int i=0;i<colorn;i++)
        {
            if(tree->maxg[i]>maxx) maxx=tree->maxg[i];
            if(tree->ming[i]<minn) minn=tree->ming[i];
        }
        printf("%d %d\n",maxx,minn);
        destroy(tree);
    }
    return 0;
}