1864: [Zjoi2006]三色二叉樹
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 773 Solved: 548
[Submit][Status][Discuss]
Description
Input
僅有一行,不超過500000個字元,表示一個二叉樹序列。
Output
輸出檔案也只有一行,包含兩個數,依次表示最多和最少有多少個點能夠被染成綠色。
Sample Input
1122002010
Sample Output
5 2
HINT
Source
先建樹
d[i][0/1]表示以i為根的子樹i綠色1其他0下最多幾個點綠色
三個顏色轉移就是父子三人兩個其他一個綠色
見程式碼
/************************************************************** Problem: 1864 User: thwfhk Language: C++ Result: Accepted Time:68 ms Memory:13884 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=5e5+5,INF=1e9; int n,mx=-INF,mn=INF; char s[N]; struct node{ int ls,rs; node():ls(0),rs(0){} }tree[N]; int cnt=0,pos=1; int build(){ int u=++cnt,num=s[pos]-'0'; pos++; if(num>=1) tree[u].ls=build(); if(num==2) tree[u].rs=build(); return u; } int d[N][2],f[N][2]; void dp(int u){//printf("dp %d\n",u); if(u==0) return; int ls=tree[u].ls,rs=tree[u].rs; dp(ls);dp(rs); d[u][0]=max(d[ls][0]+d[rs][1],d[ls][1]+d[rs][0]); f[u][0]=min(f[ls][0]+f[rs][1],f[ls][1]+f[rs][0]); d[u][1]=d[ls][0]+d[rs][0]+1; f[u][1]=f[ls][0]+f[rs][0]+1; } int main(int argc, const char * argv[]) { scanf("%s",s+1); n=strlen(s+1); build(); dp(1); mx=max(d[1][0],d[1][1]); mn=min(f[1][0],f[1][1]); printf("%d %d",mx,mn); return 0; }