F. Zublicanes and Mumocrates tree DP
Test instructions gave a tree to require that all the nodes of the tree be divided into two camps, in which the leaf nodes should be split evenly, seeking the fewest two camps adjacent, that is, the least side makes these sides of the two camps different
DP[CUR][I][J] Indicates that there are J and I-camp schemes when Cur is the I camp
Dp[cur][i][j+k] = min{dp[to][i^1][j= (number of leaves-D)]+dp[cur][i][k]+1,dp[to][i][j]+dp[cur][i][k]}
CNT is the number of leaf nodes The final answer is min{DP[ROOT][0][CNT/2], DP[ROOT][1][CNT/2]}
#include <algorithm>#include<string.h>#include<cstdio>#include<iostream>using namespacestd;Const intmaxn=5005;inth[maxn],to[maxn*2],nx[maxn*2],numofe;voidAddintUintv) {Numofe++; To[numofe]=v; Nx[numofe]=H[u]; H[u]=Numofe;}intdp[maxn][2][MAXN];intdp2[2][MAXN],SZ[MAXN];intD[MAXN];voidDfsintCur,intper) { if(d[cur]==1) {Sz[cur]=1; dp[cur][0][1]=dp[cur][1][1]=0; return ; } dp[cur][0][0]=dp[cur][1][0]=0; for(intI=h[cur]; I I=Nx[i]) { intTto =To[i]; if(Tto==per)Continue; DFS (tto,cur); for(intI=0; i<=sz[cur]; i++) for(intu=0; u<2; u++) { if(Dp[cur][u][i] = =-1)Continue; for(intj=0; j<=sz[tto]; J + +) for(intv=0; v<2; v++) { if(dp[tto][v][j]==-1)Continue; if(u==v) {if(dp2[u][i+j]==-1) { intk=dp[cur][u][i]+Dp[tto][v][j]; Dp2[u][i+J] =K; }Else { intK=min (dp[cur][u][i]+dp[tto][v][j],dp2[u][i+J]); Dp2[u][i+j]=K; } }Else { intnu=Sz[tto]; if(dp2[u][i+nu-j]==-1) { intk=dp[cur][u][i]+dp[tto][v][j]+1; Dp2[u][i+nu-j]=K; } Else { intK=min (dp[cur][u][i]+dp[tto][v][j]+1, dp2[u][i+nu-J]); Dp2[u][i+nu-j]=K; } }}} Sz[cur]+=Sz[tto]; for(intI=0; i<=sz[cur]; i++) for(intj=0; j<2; J + +) {Dp[cur][j][i]=Dp2[j][i]; Dp2[j][i]=-1; } }}intMain () {intN; while(SCANF ("%d", &n) = =1) {memset (d,0,sizeof(d)); Memset (DP,-1,sizeof(DP)); memset (SZ,0,sizeof(SZ)); memset (DP2,-1,sizeof(DP2)); memset (H,0,sizeof(H)); Numofe=0; for(intI=1; i<n; i++) { intb; scanf ("%d%d",&a,&b); Add (A, b); Add (B,a); D[a]+ +;d [b]++; } if(n==2) {printf ("%d\n",1);Continue; } intRoot; intCnt=0; for(intI=1; i<=n; i++){ if(d[i]==1) cnt++; Elseroot=i; } dfs (Root,-1); printf ("%d\n", Min (dp[root][0][cnt/2],dp[root][1][cnt/2])); } return 0;}/*6*/
View Code
Codeforces Round #322 (Div. 2)