P2585 [ZJOI2006]三色二叉树
题目
难得自己独立想出来并一次过的题目!!!后来翻了下题解自己似乎写复杂了()
首先,染绿色这东西不用管,只要用三种颜色然后最后让最大或最小的那个颜色是绿色即可。
一看题,这递归建树挺 ex 的。定义 表示 子树内的颜色 的数量。转移了一下,发现不行。
再加一维, 第一维表示 点染的颜色,第二维表示统计 子树内的哪种颜色。大力转移即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <code-pre class = "code-pre" id= "pre-FDdcQW" ><code-line class = "line-numbers-rows" ></code-line>#include <cstdio> <code-line class = "line-numbers-rows" ></code-line>#include <algorithm> <code-line class = "line-numbers-rows" ></code-line>#include <iostream> <code-line class = "line-numbers-rows" ></code-line>#include <cstring> <code-line class = "line-numbers-rows" ></code-line>#include <vector> <code-line class = "line-numbers-rows" ></code-line>#include <cmath> <code-line class = "line-numbers-rows" ></code-line>#include <queue> <code-line class = "line-numbers-rows" ></code-line>#include <map> <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line>#define ll long long <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> using namespace std; <code-line class = "line-numbers-rows" ></code-line> int rd() { <code-line class = "line-numbers-rows" ></code-line> int f=1,sum=0; char ch= getchar (); <code-line class = "line-numbers-rows" ></code-line> while (! isdigit (ch)) { if (ch== '-' ) f=-1;ch= getchar ();} <code-line class = "line-numbers-rows" ></code-line> while ( isdigit (ch)) {sum=(sum<<3)+(sum<<1)+ch- '0' ;ch= getchar ();} <code-line class = "line-numbers-rows" ></code-line> return sum*f; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line>ll lrd() { <code-line class = "line-numbers-rows" ></code-line> ll f=1,sum=0; char ch= getchar (); <code-line class = "line-numbers-rows" ></code-line> while (! isdigit (ch)) { if (ch== '-' ) f=-1;ch= getchar ();} <code-line class = "line-numbers-rows" ></code-line> while ( isdigit (ch)) {sum=(sum<<3)+(sum<<1)+ch- '0' ;ch= getchar ();} <code-line class = "line-numbers-rows" ></code-line> return sum*f; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line>#define int ll <code-line class = "line-numbers-rows" ></code-line>#define max(A,B) (A>B?A:B) <code-line class = "line-numbers-rows" ></code-line>#define min(A,B) (A>B?B:A) <code-line class = "line-numbers-rows" ></code-line> const int N=( int )(5e5+5); <code-line class = "line-numbers-rows" ></code-line> struct edge { <code-line class = "line-numbers-rows" ></code-line> int nex,to; <code-line class = "line-numbers-rows" ></code-line>}e[N<<1]; <code-line class = "line-numbers-rows" ></code-line> char str[N]; <code-line class = "line-numbers-rows" ></code-line> int head[N],cnt,tot,n,f[3][3][N]; //第一维它自己染什么颜色 <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> void add_edge( int x, int y) { <code-line class = "line-numbers-rows" ></code-line> e[++cnt].nex=head[x]; e[cnt].to=y; head[x]=cnt; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> void init( int x) { <code-line class = "line-numbers-rows" ></code-line> if (str[x]== '0' ||x>n) return ; <code-line class = "line-numbers-rows" ></code-line> if (str[x]== '2' ) { <code-line class = "line-numbers-rows" ></code-line> int pre=tot; <code-line class = "line-numbers-rows" ></code-line> add_edge(tot,tot+1),add_edge(tot+1,tot),++tot; <code-line class = "line-numbers-rows" ></code-line> init(x+1); add_edge(pre,tot+1),add_edge(tot+1,pre),++tot; <code-line class = "line-numbers-rows" ></code-line> init(x+tot-pre); <code-line class = "line-numbers-rows" ></code-line> } else { <code-line class = "line-numbers-rows" ></code-line> add_edge(tot,tot+1); add_edge(tot+1,tot); ++tot; init(x+1); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> void dfs1( int x, int ff) { <code-line class = "line-numbers-rows" ></code-line> int num=0; //cout<<x<<" "<<ff<<endl; <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> dfs1(y,x); ++num; <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> if (!num) { <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]=f[1][1][x]=f[2][2][x]=1; <code-line class = "line-numbers-rows" ></code-line> } else if (num==1) { <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]+=1+max(f[1][0][y],f[2][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[0][1][x]+=max(f[1][1][y],f[2][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[0][2][x]+=max(f[1][2][y],f[2][2][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][0][x]+=max(f[0][0][y],f[2][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][1][x]+=1+max(f[0][1][y],f[2][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][2][x]+=max(f[0][2][y],f[2][2][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][0][x]+=max(f[0][0][y],f[1][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][1][x]+=max(f[0][1][y],f[1][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][2][x]+=1+max(f[0][2][y],f[1][2][y]); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> } else { <code-line class = "line-numbers-rows" ></code-line> int ls=0,rs; <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> if (!ls) ls=y; else rs=y; <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]+=1+max(f[1][0][ls]+f[2][0][rs],f[1][0][rs]+f[2][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[0][1][x]+=max(f[1][1][ls]+f[2][1][rs],f[1][1][rs]+f[2][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[0][2][x]+=max(f[1][2][ls]+f[2][2][rs],f[1][2][rs]+f[2][2][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][0][x]+=max(f[0][0][ls]+f[2][0][rs],f[0][0][rs]+f[2][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][1][x]+=1+max(f[0][1][ls]+f[2][1][rs],f[0][1][rs]+f[2][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][2][x]+=max(f[0][2][ls]+f[2][2][rs],f[0][2][rs]+f[2][2][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][0][x]+=max(f[0][0][ls]+f[1][0][rs],f[0][0][rs]+f[1][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][1][x]+=max(f[0][1][ls]+f[1][1][rs],f[0][1][rs]+f[1][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][2][x]+=1+max(f[0][2][ls]+f[1][2][rs],f[0][2][rs]+f[1][2][ls]); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> void dfs2( int x, int ff) { <code-line class = "line-numbers-rows" ></code-line> int num=0; //cout<<x<<" "<<ff<<endl; <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> dfs2(y,x); ++num; <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> if (!num) { <code-line class = "line-numbers-rows" ></code-line> for ( int i=0;i<3;i++) for ( int j=0;j<3;j++) f[i][j][x]=0; <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]=f[1][1][x]=f[2][2][x]=1; <code-line class = "line-numbers-rows" ></code-line> } else if (num==1) { <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]+=1+min(f[1][0][y],f[2][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[0][1][x]+=min(f[1][1][y],f[2][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[0][2][x]+=min(f[1][2][y],f[2][2][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][0][x]+=min(f[0][0][y],f[2][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][1][x]+=1+min(f[0][1][y],f[2][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[1][2][x]+=min(f[0][2][y],f[2][2][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][0][x]+=min(f[0][0][y],f[1][0][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][1][x]+=min(f[0][1][y],f[1][1][y]); <code-line class = "line-numbers-rows" ></code-line> f[2][2][x]+=1+min(f[0][2][y],f[1][2][y]); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> } else { <code-line class = "line-numbers-rows" ></code-line> int ls=0,rs; <code-line class = "line-numbers-rows" ></code-line> for ( int i=head[x];i;i=e[i].nex) { <code-line class = "line-numbers-rows" ></code-line> int y=e[i].to; if (y==ff) continue ; <code-line class = "line-numbers-rows" ></code-line> if (!ls) ls=y; else rs=y; <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line> f[0][0][x]+=1+min(f[1][0][ls]+f[2][0][rs],f[1][0][rs]+f[2][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[0][1][x]+=min(f[1][1][ls]+f[2][1][rs],f[1][1][rs]+f[2][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[0][2][x]+=min(f[1][2][ls]+f[2][2][rs],f[1][2][rs]+f[2][2][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][0][x]+=min(f[0][0][ls]+f[2][0][rs],f[0][0][rs]+f[2][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][1][x]+=1+min(f[0][1][ls]+f[2][1][rs],f[0][1][rs]+f[2][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[1][2][x]+=min(f[0][2][ls]+f[2][2][rs],f[0][2][rs]+f[2][2][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][0][x]+=min(f[0][0][ls]+f[1][0][rs],f[0][0][rs]+f[1][0][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][1][x]+=min(f[0][1][ls]+f[1][1][rs],f[0][1][rs]+f[1][1][ls]); <code-line class = "line-numbers-rows" ></code-line> f[2][2][x]+=1+min(f[0][2][ls]+f[1][2][rs],f[0][2][rs]+f[1][2][ls]); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> signed main() { <code-line class = "line-numbers-rows" ></code-line> scanf ( "%s" ,str+1); n= strlen (str+1); <code-line class = "line-numbers-rows" ></code-line> tot=1; init(1); <code-line class = "line-numbers-rows" ></code-line> dfs1(1,0); int ans1=0,ans2=2e18; for ( int i=0;i<3;i++) for ( int j=0;j<3;j++) ans1=max(ans1,f[i][j][1]); <code-line class = "line-numbers-rows" ></code-line> memset (f,0, sizeof (f)); <code-line class = "line-numbers-rows" ></code-line> dfs2(1,0); for ( int i=0;i<3;i++) for ( int j=0;j<3;j++) ans2=min(ans2,f[i][j][1]); <code-line class = "line-numbers-rows" ></code-line> printf ( "%lld %lld" ,ans1,ans2); return 0; <code-line class = "line-numbers-rows" ></code-line>} </code-pre> |
__EOF__

本文作者:F x o r G
本文链接:https://www.cnblogs.com/xugangfan/p/15177092.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/xugangfan/p/15177092.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】