BZOJ1864 [ZJOI2006] 三色二叉树

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1864

Description

Input

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

Output

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

 

树DP

用f[x][0]表示编号为x的点不染成绿色,f[x][1]表示编号为x的点染成绿色

f[x][0] = max (或min) (f[l[x]][0] + f[r[x]][1], f[r[x]][0] + f[l[x]][1]);
f[x][1] = f[l[x]][0] + f[r[x]][0] + 1;

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #define rep(i,l,r) for(int i=l; i<=r; i++)
 5 #define clr(x,y) memset(x,y,sizeof(x))
 6 using namespace std;
 7 const int INF = 0x3f3f3f3f;
 8 const int maxn = 500010;
 9 int tot=1,l[maxn],r[maxn],f[maxn][2];
10 void dfs(int x){
11     char ch = getchar();
12     if (ch == '0') return;
13     tot++; l[x] = tot; dfs(tot);
14     if (ch == '2'){
15         tot++; r[x] = tot; dfs(tot);
16     }
17 }
18 void dp1(int x){
19     if (!x) return;
20     dp1(l[x]); dp1(r[x]);
21     f[x][0] = max(f[l[x]][0] + f[r[x]][1], f[r[x]][0] + f[l[x]][1]);
22     f[x][1] = f[l[x]][0] + f[r[x]][0] + 1;
23 }
24 void dp2(int x){
25     if (!x) return;
26     dp2(l[x]); dp2(r[x]);
27     f[x][0] = min(f[l[x]][0] + f[r[x]][1], f[r[x]][0] + f[l[x]][1]);
28     f[x][1] = f[l[x]][0] + f[r[x]][0] + 1;
29 }
30 int main(){
31     clr(l,0); clr(r,0); dfs(1);
32     clr(f,0); dp1(1); printf("%d ",max(f[1][0],f[1][1]));
33     clr(f,0); dp2(1); printf("%d\n",min(f[1][0],f[1][1]));
34     return 0;
35 }
View Code

 

posted on 2015-12-21 14:12  ACMICPC  阅读(178)  评论(0编辑  收藏  举报

导航