[luogu2585 ZJOI2006] 三色二叉树 (树形dp)
Description
Input
输入文件名:TRO.IN
输入文件仅有一行,不超过500000个字符,表示一个二叉树序列。
Output
输出文件名:TRO.OUT
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
Sample Input
1122002010
Sample Output
5 2
Code:
//By Menteur_Hxy
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ls nd[x][0]
#define rs nd[x][1]
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=500010;
int tot=1;
int nd[N][2],f[N][3],g[N][3];
void build(int x) {
char c=getchar();
if(c=='1'||c=='2') nd[x][0]=++tot,build(tot);
if(c=='2') nd[x][1]=++tot,build(tot);
if(c=='0') f[x][2]=g[x][2]=1;
}
void dfs(int x) {
if(ls) {
dfs(ls);
if(rs) {
dfs(rs);
f[x][0]=min(f[ls][1]+f[rs][2],f[ls][2]+f[rs][1]);
f[x][1]=min(f[ls][0]+f[rs][2],f[ls][2]+f[rs][0]);
f[x][2]=min(f[ls][0]+f[rs][1]+1,f[ls][1]+f[rs][0]+1);
g[x][0]=max(g[ls][1]+g[rs][2],g[ls][2]+g[rs][1]);
g[x][1]=max(g[ls][0]+g[rs][2],g[ls][2]+g[rs][0]);
g[x][2]=max(g[ls][0]+g[rs][1]+1,g[ls][1]+g[rs][0]+1);
} else {
f[x][0]=min(f[ls][1],f[ls][2]);
f[x][1]=min(f[ls][0],f[ls][2]);
f[x][2]=min(f[ls][0],f[ls][1])+1;
g[x][0]=max(g[ls][1],g[ls][2]);
g[x][1]=max(g[ls][0],g[ls][2]);
g[x][2]=max(g[ls][0],g[ls][1])+1;
}
}
}
int main() {
build(1);
dfs(1);
int maxn=max(g[1][0],max(g[1][1],g[1][2]));
int minn=min(f[1][0],min(f[1][1],f[1][2]));
printf("%d %d",maxn,minn);
return 0;
}
PS:写几道简单的树形dp qwq
版权声明:本文为博主原创文章,未经博主允许不得转载。
博主:https://www.cnblogs.com/Menteur-Hxy/