P2585 [ZJOI2006]三色二叉树 解题报告

原题链接

考察:树形dp

思路:

        树上最大值,最小值,方案数是树形dp常考的问题.这里设置f[i][j]为在以i为根的子树中,i的颜色是j的最大结点数.

        设置2为绿色,初始化所有f[i][2] = 1.如果当前父节点u只有一个子结点x f[u][k] += max(f[x][j]) j!=k.

        如果有两个子结点,就需要三个结点的颜色互不相同. 此时可以先计算完两个子结点再计算父节点,而非常规树形dp枚举一个子结点就更新父节点

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 typedef long long LL;
 7 const int N = 500010,M = 1e6+10;
 8 char s[N];
 9 int idx = 1,len,p=1;
10 vector<int> v[M];
11 LL f[M][3][2];
12 void build(int st)
13 {
14     if(p>len) return;
15     int sz = s[p]-'0';
16     p++;
17     while(sz--)
18         v[st].push_back(++idx);
19     for(int i=0;i<v[st].size();i++)
20         build(v[st][i]);
21 }
22 void dfs(int u)
23 {
24     f[u][2][0] = f[u][2][1] = 1;
25     for(int i=0;i<v[u].size();i++)
26     {
27         int t = v[u][i];
28         dfs(t);
29     }
30     if(v[u].size()==1)
31     {
32         int x = v[u][0];
33         for(int i=0;i<3;i++)
34         {
35           LL val = 0,minv = (1ll<<63)-1;
36           for(int j=0;j<3;j++)
37             if(i!=j) val = max(f[x][j][0],val),minv = min(f[x][j][1],minv); 
38           f[u][i][0]+=val;
39           f[u][i][1]+=minv;
40         }
41     }else if(v[u].size()==2)
42     {
43         int x = v[u][0],y = v[u][1];
44         for(int i=0;i<3;i++)
45         {
46             LL val = 0,minv = (1ll<<63)-1;
47             for(int j=0;j<3;j++)
48               for(int k=0;k<3;k++)
49                 if(i!=j&&j!=k&&k!=i)
50                  val=max(f[x][j][0]+f[y][k][0],val),minv = min(f[x][j][1]+f[y][k][1],minv);
51             f[u][i][0]+=val;
52             f[u][i][1]+=minv;
53         }
54     }
55 }
56 int main()
57 {
58     scanf("%s",s+1);
59     len = strlen(s+1);
60     build(1);
61     dfs(1);
62     LL maxn = 0,minv = (1ll<<63)-1;
63     for(int i=0;i<3;i++) maxn = max(f[1][i][0],maxn),minv= min(f[1][i][1],minv);
64     printf("%lld %lld\n",maxn,minv);
65     return 0;
66 }

 

posted @ 2021-04-08 19:06  acmloser  阅读(59)  评论(0编辑  收藏  举报