zoukankan      html  css  js  c++  java
  • [BZOJ1864][Zjoi2006]三色二叉树

    Description

    Input

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

    Output

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

    Sample Input

    1122002010

    Sample Output

    5 2


    仔细考虑我们发现,一个节点的颜色只有是绿色和不是绿色两种。

    如果一个点x不是绿色,那么根据抽屉原理,它的两个儿子一定是一个绿色,一个不是绿色。

    如果这个点是绿色,那么它的两个儿子一定都不是绿色,然后又回到了上面那一条。

    归纳得证。

    所以我们设f[x][0/1]为x节点不是绿色/是绿色,它的子树的最多的绿色点的个数。

    显然f[x][1] = f[ls[x]][0] + f[rs[x]][0] + 1;

    f[x][0] = max(f[ls[x][0] + f[rs[x]][1], f[rs[x][0] + f[ls[x]][1]).

    最小值同理。

    这题的读入比较有意思...递归读入...


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm> 
    using namespace std;
    
    int ls[500005], rs[500005], cnt;
    
    void in(int x)
    {
        int y ;
        scanf("%1d", &y);
        if (y == 1) in(ls[x]=++cnt);
        else if (y == 2)in(ls[x]=++cnt), in(rs[x]=++cnt);
    }
    
    int f[500005][2];//1:绿色,0:不是绿色 
    int g[500005][2];
    
    void dfs(int x)
    {
        if (ls[x]) dfs(ls[x]);
        if (rs[x]) dfs(rs[x]);
        f[x][1] = max(f[x][1], f[ls[x]][0] + f[rs[x]][0] + 1);
        f[x][0] = max(f[x][0], max(f[ls[x]][1] + f[rs[x]][0], f[rs[x]][1] + f[ls[x]][0]));
    }
    
    void efs(int x)
    {
        if (ls[x]) efs(ls[x]);
        if (rs[x]) efs(rs[x]);
        g[x][1] = g[ls[x]][0] + g[rs[x]][0] + 1;
        g[x][0] = min(g[ls[x]][1] + g[rs[x]][0], g[rs[x]][1] + g[ls[x]][0]);    
    }
    
    int main()
    {
        in(++cnt);
        dfs(1);
        efs(1);
        printf("%d %d
    ", max(f[1][1], f[1][0]), min(g[1][1], g[1][0]));
        return 0;
    }
  • 相关阅读:
    shutil文件去重模块
    Nexus构建npm、yum、maven私有仓库
    centos7添加自定义服务到systemctl
    Sonatype nuxus私有仓库介绍
    rancher单节点备份和恢复
    rancher证书过期X509:certificate has expired or is not ye valid
    清理docker日志
    mysql 9 hash索引和B+tree索引的区别
    mysql 8 索引
    mysql 7 慢查询+慢查询工具
  • 原文地址:https://www.cnblogs.com/BriMon/p/9381946.html
Copyright © 2011-2022 走看看