BZOJ1864 [Zjoi2006]三色二叉树

Description:

Input

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

Output

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

Analysis:

f[x][0/1] := 表示 x 结点为非绿/绿色子树的绿色结点的最大个数
f[x][1] = f[l[x]][0] + f[r[x]][0] + 1
f[x][0] = max(f[l[x]][1] + f[r[x]][0],f[l[x]][0] + f[r[x]][1])

Code

#include<vector> 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 500010;
int f[N][2],l[N],r[N],n;
void dfs(int p)
{
	char ch = getchar();
	if(ch == '0') return;
	l[p] = ++n;
	dfs(n);
	if(ch == '2'){
		r[p] = ++n;
		dfs(n);
	}
}
void dp1(int x)
{
	if(!x) return;
	dp1(l[x]);dp1(r[x]);
	f[x][1] = f[l[x]][0] + f[r[x]][0] + 1;
	f[x][0] = max(f[l[x]][1] + f[r[x]][0],f[l[x]][0] + f[r[x]][1]);
}
void dp2(int x)
{
	if(!x) return;
	dp2(l[x]);dp2(r[x]);
	f[x][1] = f[l[x]][0] + f[r[x]][0] + 1;
	f[x][0] = min(f[l[x]][1] + f[r[x]][0],f[l[x]][0] + f[r[x]][1]);
}
int main()
{
	n = 1;
	dfs(1);
	dp1(1);
	int ans1 = max(f[1][0],f[1][1]);
	memset(f,0,sizeof(f));
	dp2(1);
	int ans2 = min(f[1][0],f[1][1]);
	printf("%d %d\n",ans1,ans2);
	return 0;
}
惊天魔盗团2盗窃芯片精彩片段1080p
posted @ 2019-09-06 21:38  Zforw  阅读(63)  评论(0编辑  收藏  举报