[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]));
}
 
 
 
posted @ 2017-09-19 20:19  orzzz  阅读(308)  评论(0编辑  收藏  举报