码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1864 [ZJOI2006] 三色二叉树

时间:2015-12-21 16:06:20      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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

 

BZOJ1864 [ZJOI2006] 三色二叉树

标签:

原文地址:http://www.cnblogs.com/jimzeng/p/bzoj1864.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!