题目链接
题目大意:给出1个表示二叉树的字符串,每个节点可以染红绿蓝三色,1个节点与其子节点不同色,1个节点与其兄弟节点不同色,求最多/最少的绿色节点数目
题解:因为序列是递归定义的,可以方便地读入
min和max是相同的,下面考虑min
f[i][0]表示i不是绿色的最优解,f[x][0]=0
f[i][1]表示i是绿色的最优解,f[x][1]=1
转移时f[i][0]时只有两种情况,取min/max即可
我的收获:递归读入树
#include
#include
#include
using namespace std;
const int M=500005;
int rt,cnt,flag;
int c[M][2],f[M][2];
char s[M];
void build(int &x)
{
x=++cnt;int t=s[x]-'0';
if(t) build(c[x][0]);if(t==2) build(c[x][1]);
}
inline int get(int x,int y){if(flag) return x>y?x:y;return xvoid dfs(int x)
{
if(!x) return ;
f[x][1]=1,f[x][0]=0;
int l=c[x][0],r=c[x][1];
dfs(l);dfs(r);
f[x][0]=get(f[l][0]+f[r][1],f[l][1]+f[r][0]);
f[x][1]+=f[l][0]+f[r][0];
}
void work(){
flag=1;dfs(1);
printf("%d ",max(f[1][0],f[1][1]));
flag=0;dfs(1);
printf("%d\n",min(f[1][0],f[1][1]));
}
void init(){
scanf("%s",s+1);build(rt);
}
int main()
{
init();
work();
return 0;
}