BZOJ -1864: [Zjoi2006]三色二叉树

来源:互联网 发布:软件架构师证书 编辑:程序博客网 时间:2024/04/29 02:30

1864: [Zjoi2006]三色二叉树

Time Limit: 1 Sec Memory Limit: 64 MB Submit: 662 Solved: 472
[Submit][Status][Discuss] Description
这里写图片描述 Input

仅有一行,不超过500000个字符,表示一个二叉树序列。

Output

输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。

Sample Input

1122002010

Sample Output

5 2

HINT

Source

Day1

树形DP,不难

f[i][j]表示i节点颜色为j的最小花费。   2为绿色。一个孩子时:f[i][0]=max(f[son[i]][1],f[son[i]][2]);               f[i][1]=max(f[son[i]][0],f[son[i]][2]);               f[i][2]=max(f[son[i]][1],f[son[i]][0])+1;两个时:   f[i][0]=max(f[ls[i]][1]+f[rs[i]][2],f[ls[i]][2]+f[rs[i]][1]);          f[i][1]=max(f[ls[i]][0]+f[rs[i]][2],f[ls[i]][2]+f[rs[i]][0]);          f[i][2]=max(f[ls[i]][1]+f[rs[i]][0],f[ls[i]][0]+f[rs[i]][1])+1;

输入不好处理呦,我用的递归?!
代码:

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>const int maxn = 500010;using namespace std;struct tree{    int sum;    int son[3];}node[maxn];int tot;int f[maxn][3];int g[maxn][3];int my_min(int x,int y,int z){    return min(min(x,y),z);}int my_max(int x,int y,int z){    return max(max(x,y),z);}int read(){    tot++;    int id=tot;    char c=getchar();    c=c-'0';    for(int i=1;i<=c;i++)    {        node[id].sum++;        node[id].son[i]=read();    }    return id;}void dp(int x){    int s=node[x].sum;    int u=node[x].son[1];    int v=node[x].son[2];    if(u) dp(u);    if(v) dp(v);    if(s==1)    {        f[x][0]=min(f[u][1],f[u][2]);        f[x][1]=min(f[u][0],f[u][2]);        f[x][2]=min(f[u][1],f[u][0]);        g[x][0]=max(g[u][1],g[u][2]);        g[x][1]=max(g[u][0],g[u][2]);        g[x][2]=max(g[u][1],g[u][0]);    }    if(s==2)    {        f[x][0]=min(f[u][1]+f[v][2],f[u][2]+f[v][1]);        f[x][1]=min(f[u][0]+f[v][2],f[u][2]+f[v][0]);        f[x][2]=min(f[u][1]+f[v][0],f[u][0]+f[v][1]);        g[x][0]=max(g[u][1]+g[v][2],g[u][2]+g[v][1]);        g[x][1]=max(g[u][0]+g[v][2],g[u][2]+g[v][0]);        g[x][2]=max(g[u][1]+g[v][0],g[u][0]+g[v][1]);    }    f[x][2]++;    g[x][2]++;}int main(){    read();    dp(1);    printf("%d %d",my_max(g[1][0],g[1][1],g[1][2]),my_min(f[1][0],f[1][1],f[1][2]));    return 0;}
1 0
原创粉丝点击