zoukankan      html  css  js  c++  java
  • [bzoj2932][POI1999]树的染色问题

    被百度搜到的题解(论文?)坑了。

    写的那玩意好像石乐志。。。


    Description

    一棵二叉树采用以下规则描述:
    1.如果一个节点度数为0,则仅用一个元素“0”来描述它。
    2.如果一个节点度数为1,则对它的描述以“1”开头,后面接着对它的孩子的描述。
    3.如果一个节点度数为2,则对它的描述以“2”开头,后面接着的首先是它的左孩子的描述,然后是右孩子的描述。
    在树中每一个节点必须被着为红色、绿色或蓝色。然而,我们必须遵循如下规定:
    1.根点和它的孩子不能有相同的颜色。
    2.如果一个节点有两个孩子,那么这两个节点必定有两个不同的颜色。
    有多少个节点可以被着为绿色呢?
    任务
    写一个程序:
    1.读取对一棵树的描述。
    2.计算可以被着为绿色的节点的最大值和最小值。
    3.把结果输出

    Input

    首行是由一个字符串组成(不长于10000字符),它是对一棵树的描述。

    Output

    首行两个用空格隔开的整数,它们分别表示可以被着为绿色的节点的最大和最小数目。

    Sample Input

    1122002010

    Sample Output

    5 2
    其实很傻的一道题。一看AC数和Submit数就知道了。
    简单树dp即可。代码十分工整且难看。。。
    #include<bits/stdc++.h>
    #define L t[u].ls
    #define R t[u].rs
    using namespace std;
    const int mxn=10010;
    inline int read(){
        int r=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){r=r*10+c-'0';c=getchar();}
        return r*f;
    }
    int n,c=1;
    char s[mxn];
    struct Node{
        int ls,rs;
    }t[mxn];
    void dfs1(int u){
        if(s[u]=='0'){
            t[u].ls=t[u].rs=-1;
        }
        else if(s[u]=='1'){
            c++;t[u].ls=c;
            dfs1(c);
            t[u].rs=-1;
        }
        else{
            c++;t[u].ls=c;
            dfs1(c);
            c++;t[u].rs=c;
            dfs1(c);
        }
    }
    void init(){
        scanf("%s",s+1);
        n=strlen(s+1);
        dfs1(1);
    }
    int f[mxn][3],g[mxn][3];
    void dfs2(int u){
        f[u][0]=g[u][0]=1;
        f[u][1]=g[u][1]=0;
        f[u][2]=g[u][2]=0;
        if(s[u]=='0')return;
        dfs2(L);
        if(!~R){
            f[u][0]+=max(f[L][1],f[L][2]);
            f[u][1]+=max(f[L][0],f[L][2]);
            f[u][2]+=max(f[L][0],f[L][1]);
            g[u][0]+=min(g[L][1],g[L][2]);
            g[u][1]+=min(g[L][0],g[L][2]);
            g[u][2]+=min(g[L][0],g[L][1]);
        }
        else{
            dfs2(R);
            f[u][0]+=max(f[L][1]+f[R][2],f[L][2]+f[R][1]);
            f[u][1]+=max(f[L][0]+f[R][2],f[L][2]+f[R][0]);
            f[u][2]+=max(f[L][0]+f[R][1],f[L][1]+f[R][0]);
            g[u][0]+=min(g[L][1]+g[R][2],g[L][2]+g[R][1]);
            g[u][1]+=min(g[L][0]+g[R][2],g[L][2]+g[R][0]);
            g[u][2]+=min(g[L][0]+g[R][1],g[L][1]+g[R][0]);
        }
    }
    int main(){
        init();
        dfs2(1);
        cout<<max(f[1][0],max(f[1][1],f[1][2]))<<' '<<min(g[1][0],min(g[1][1],g[1][2]));
    }
     
     
     
  • 相关阅读:
    BZOJ 2300凸包+离线
    BZOJ 4140 凸包+二进制分组
    BZOJ 2178 Simpson积分
    BZOJ 4828 DP+BFS
    BZOJ 1845 Simpson积分
    BZOJ 1137 半平面交
    Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树
    Codeforces Round 411 Div.2 题解
    BZOJ 4530 LCT/线段树合并
    BZOJ 2946 SA/SAM
  • 原文地址:https://www.cnblogs.com/orzzz/p/7553882.html
Copyright © 2011-2022 走看看