zoukankan      html  css  js  c++  java
  • 三色二叉树_树形DP

    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
    ",maxx,minn);
            destroy(tree);
        }
        return 0;
    }
  • 相关阅读:
    自己遇到的冲突及解决方案
    怎么解决代码冲突及切换分支
    程序员修养
    代码回退
    gitlab两种连接方式:ssh和http配置介绍
    gitlab创建项目及分支
    github,gitlab的区别
    代码托管有什么用
    新手搭建云服务器详细过程
    UNP学习笔记(第十一章 名字与地址转换)
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5842542.html
Copyright © 2011-2022 走看看