• P2585 [ZJOI2006]三色二叉树


    题目描述

    输入输出格式

    输入格式:

    输入文件名:TRO.IN

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

    输出格式:

    输出文件名:TRO.OUT

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

    输入输出样例

    输入样例#1: 
    1122002010
    输出样例#1:
    5 2

    树形dp
    可以发现,只要不是绿色,红色或蓝色对于答案是没有影响的。
    所以题目变成:在一棵二叉树上,每个有两个儿子节点和他的2个儿子中一定要有一个绿色节点切相邻的两个节点不能同时是绿色时求绿色节点数量的最大值和最小值。
    然后就是基础的树形dp啦!要注意的是这道题的建图需要一定的技巧。
    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    using namespace std;
    
    int i,m,n,j,k,a[500005][4],f[500005],son[500005][2],d[500005];
    
    int dfs(int x,int fa)
    {
        scanf("%1ld",&d[x]);
        f[x]=fa;
        if(fa)
        {
            if(son[fa][0]) son[fa][1]=x;
            else son[fa][0]=x;
        }
        if(d[x]==0) return x;
        if(d[x]==2) return dfs(dfs(x+1,x)+1,x);
        return dfs(x+1,x);
    }
    
    void ddfs(int x)
    {
        if(!x) return;
        if(!d[x]) 
        {
            a[x][1]=a[x][3]=1;
            return;
        }
        ddfs(son[x][0]); ddfs(son[x][1]);
        a[x][0]=max(a[son[x][0]][1]+a[son[x][1]][0],a[son[x][0]][0]+a[son[x][1]][1]);
        a[x][1]=1+a[son[x][0]][0]+a[son[x][1]][0];
        a[x][2]=min(a[son[x][0]][3]+a[son[x][1]][2],a[son[x][0]][2]+a[son[x][1]][3]);
        a[x][3]=1+a[son[x][0]][2]+a[son[x][1]][2];
    }
    
    int main()
    {
        dfs(1,0);
        ddfs(1);
        printf("%d %d",max(a[1][0],a[1][1]),min(a[1][2],a[1][3]));
    }
  • 相关阅读:
    C#中的WebBrowser控件的使用
    触发器
    SQL Server存储机制
    mongodb客户端操作常用命令
    动态居中方法
    关于node不需要重启即可刷新页面
    测试一个段落里面是否含有数字
    表单验证
    关于echarts和jquery的结合使用问题
    js函数获取ev对象
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9340496.html
Copyright © 2020-2023  润新知