zoukankan      html  css  js  c++  java
  • bzoj 1864 三色二叉树

    Written with StackEdit.

    Description

    Input

    仅有一行,不超过(5*10^5)个字符,表示一个二叉树序列。

    Output

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

    Sample Input

    1122002010

    Sample Output

    5 2

    Solution

    • 一道比较水的树形(dp).
    • 读入考察递归的使用.然后就是一个(ex-)没有上司的舞会.
    • (f[i][0/1/2])表示当(i)的颜色分别为绿,红,蓝时,根节点为(i)的子树的最大绿点数.
    • (g[i][0/1/2])表示当(i)的颜色分别为绿,红,蓝时,根节点为(i)的子树的最小绿点数,
    • 然后就是弱智一般的转移了.
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LoveLive;
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		{
    			fh=-1;
    			jp=getchar();
    		}
    	while (jp>='0'&&jp<='9')
    		{
    			out=out*10+jp-'0';
    			jp=getchar();
    		}
    	return out*fh;
    }
    const int MAXN=5e5+10;
    int idx=1;
    int ls[MAXN],rs[MAXN],sons[MAXN];
    void readtree(int x)
    {
    	char ch=getchar();
    	if(ch=='1')
    		{
    			ls[x]=++idx;
    			readtree(idx);
    			sons[x]=1;
    		}
    	if(ch=='2')
    		{
    			ls[x]=++idx;
    			readtree(idx);
    			rs[x]=++idx;
    			readtree(idx);
    			sons[x]=2;
    		}
    }
    int f[MAXN][3];//max
    int g[MAXN][3];//min
    //0 green
    //1 red
    //2 blue 
    void dfs(int u)
    {
    	if(sons[u]==0)
    		{
    			f[u][0]=1;
    //			f[u][1]=0;
    //			f[u][2]=0;
    			g[u][0]=1;
    //			g[u][1]=0;
    //			g[u][2]=0;
    		}
    	#define l ls[u]
    	#define r rs[u]
    	else if(sons[u]==1)
    		{
    			dfs(l);
    			f[u][0]=max(f[l][1],f[l][2])+1;
    			f[u][1]=max(f[l][0],f[l][2]);
    			f[u][2]=max(f[l][0],f[l][1]);
    			
    			g[u][0]=min(g[l][1],g[l][2])+1;
    			g[u][1]=min(g[l][0],g[l][2]);
    			g[u][2]=min(g[l][0],g[l][1]);
    		}
    	else if(sons[u]==2)
    		{
    			dfs(l);
    			dfs(r);
    			f[u][0]=max(f[l][1]+f[r][2],f[l][2]+f[r][1])+1;
    			f[u][1]=max(f[l][0]+f[r][2],f[l][2]+f[r][0]);
    			f[u][2]=max(f[l][0]+f[r][1],f[l][1]+f[r][0]);
    			
    			g[u][0]=min(g[l][1]+g[r][2],g[l][2]+g[r][1])+1;
    			g[u][1]=min(g[l][0]+g[r][2],g[l][2]+g[r][0]);
    			g[u][2]=min(g[l][0]+g[r][1],g[l][1]+g[r][0]);
    		}
    }
    int main()
    {
    	readtree(1);
    	dfs(1);
    	int maxans=max(f[1][0],max(f[1][1],f[1][2]));
    	int minans=min(g[1][0],min(f[1][1],g[1][2]));
    	printf("%d %d
    ",maxans,minans);
    	return 0;
    }
    
  • 相关阅读:
    029- 位运算符
    028- 三目运算符
    027- 字符串链接运算符
    026- 布尔运算符
    lucene 结合数据库做搜索
    JDK 1.8判断集合种的元素是否存在相同
    Springboot 集成jpa使用
    json 的使用 Java对象转json
    Java 短信发送
    1 eclipse 离线安装activiti插件
  • 原文地址:https://www.cnblogs.com/jklover/p/10071498.html
Copyright © 2011-2022 走看看