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

BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

时间:2018-02-08 20:26:16      阅读:346      评论:0      收藏:0      [点我收藏+]

标签:names   ++   gif   span   src   ima   har   节点   zjoi2006   

BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

题意:

技术分享图片

分析:递归建树,然后DP,从子节点转移。

注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的。这样的话我们只需要知道当前节点是否为绿色即可。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 500050
 6 int lson[N],rson[N],cnt,n;
 7 int f[N][2],g[N][2],h[N][2];
 8 void build(int x)
 9 {
10     char s=getchar();
11     if(s==0)return ;
12     lson[x]=++cnt;build(lson[x]);
13     if(s==2)
14     {
15         rson[x]=++cnt;build(rson[x]);    
16     }
17 }
18 void dfs(int x)
19 {
20     int u=lson[x],v=rson[x];
21     if(u==0&&v==0)
22     {
23         f[x][0]=f[x][1]=1;
24         return ;
25     }
26     dfs(u);    
27     if(v)
28     {
29         dfs(v);    
30         f[x][0]=max(g[u][0]+h[v][0],g[v][0]+h[u][0])+1;
31         g[x][0]=max(f[u][0]+h[v][0],f[v][0]+h[u][0]);
32         h[x][0]=max(f[u][0]+g[v][0],f[v][0]+g[u][0]);
33         f[x][1]=min(g[u][1]+h[v][1],g[v][1]+h[u][1])+1;
34         g[x][1]=min(f[u][1]+h[v][1],f[v][1]+h[u][1]);
35         h[x][1]=min(f[u][1]+g[v][1],f[v][1]+g[u][1]);
36     }
37     else
38     {
39         f[x][0]=max(g[u][0],h[u][0])+1;
40         h[x][0]=max(f[u][0],g[u][0]);
41         g[x][0]=max(f[u][0],h[u][0]);
42         f[x][1]=min(g[u][1],h[u][1])+1;
43         h[x][1]=min(f[u][1],g[u][1]);
44         g[x][1]=min(f[u][1],h[u][1]);        
45     }
46 }
47 int main()
48 {
49     cnt=1;
50     build(1);
51     dfs(1); 
52     printf("%d %d",max(max(f[1][0],g[1][0]),h[1][0]),min(min(f[1][1],g[1][1]),h[1][1]));
53 }

 

BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

标签:names   ++   gif   span   src   ima   har   节点   zjoi2006   

原文地址:https://www.cnblogs.com/suika/p/8432461.html

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