Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:
你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。
Input
输入数据由多组数据组成。
每组数据仅有一行,不超过10000个字符,表示一个二叉树序列。
每组数据仅有一行,不超过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; }