题目大意:给定一棵树,每个结点有一个值,求一棵含k个结点的子树,使子树的值最大。(树的值为所含结点的值的和)
分析:n最大为100,定义状态dp[u][k]为以结点u为根结点且含k个结点的子树的最大值。用左二子右兄弟来存树,不难写出状态转移方程。
纠结之处在于使用memset(dp,-1,sizeof(dp))就WA,改成memset(dp,0xff,sizeof(dp))就AC了。其中还有好几次CE莫名其妙,提示信息为"Getting complication error information failed!"
AC的代码
1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 101 5 int son[N],bro[N],n,k; 6 int u[2*N],v[2*N],next[2*N],first[N]; 7 long long dp[N][N],w[N],ans; 8 void addEdge(int a,int b,int e) 9 { 10 u[e]=a,v[e]=b; 11 next[e]=first[a]; 12 first[a]=e; 13 } 14 void dfs(int a,int fa) 15 { 16 int e,b; 17 for(e=first[a];e>=0;e=next[e]) 18 { 19 b=v[e]; 20 if(b==fa) continue; 21 if(son[a]==-1) son[a]=b; 22 else bro[b]=bro[son[a]],bro[son[a]]=b; 23 dfs(b,a); 24 } 25 } 26 long long dptree(int a,int k) 27 { 28 int i,ret; 29 if(a<0) return 0; 30 if(dp[a][k]!=-1) return dp[a][k]; 31 if(k==0) return dp[a][k]=0; 32 if(k==1) return dp[a][k]=w[a]; 33 ret=w[a]; 34 if(son[a]==-1) return dp[a][k]=ret; 35 for(i=0;i<k;i++) ret=MAX(ret,w[a]+dptree(son[a],i)+dptree(bro[son[a]],k-1-i)); 36 return dp[a][k]=ret; 37 } 38 int main() 39 { 40 int i,j,a,b; 41 while(~scanf("%d%d",&n,&k)) 42 { 43 for(i=0;i<n;i++) scanf("%lld",&w[i]); 44 memset(next,0xff,sizeof(next)); 45 memset(first,0xff,sizeof(first)); 46 for(i=0;i<n-1;i++) 47 { 48 scanf("%d%d",&a,&b); 49 addEdge(a,b,2*i); 50 addEdge(b,a,2*i+1); 51 } 52 memset(son,0xff,sizeof(son)); 53 memset(bro,0xff,sizeof(bro)); 54 memset(dp,0xff,sizeof(dp)); 55 dfs(0,-1); 56 ans=0; 57 for(i=0;i<n;i++) ans=MAX(ans,dptree(i,k)); 58 printf("%lld\n",ans); 59 } 60 return 0; 61 }
奇怪的CE
1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 101 5 int son[N],bro[N],n,k; 6 int u[2*N],v[2*N],next[2*N],first[N]; 7 long long dp[N][N],w[N],ans; 8 void addEdge(int a,int b,int e) 9 { 10 u[e]=a,v[e]=b; 11 next[e]=first[a]; 12 first[a]=e; 13 } 14 void dfs(int a,int fa) 15 { 16 int e,b; 17 for(e=first[a];e>=0;e=next[e]) 18 { 19 b=v[e]; 20 if(b==fa) continue; 21 if(son[a]==-1) son[a]=b; 22 else bro[b]=bro[son[a]],bro[son[a]]=b; 23 dfs(b,a); 24 } 25 } 26 long long dptree(int a,int k) 27 { 28 int i,ret; 29 if(a<0) return 0; 30 if(dp[a][k]!=-1) return dp[a][k]; 31 if(k==0) return dp[a][k]=0; 32 if(k==1) return dp[a][k]=w[a]; 33 ret=w[a]; 34 if(son[a]==-1) return dp[a][k]=ret; 35 for(i=0;i<k;i++) ret=MAX(ret,w[a]+dptree(son[a],i)+dptree(bro[son[a]],k-1-i)); 36 return dp[a][k]=ret; 37 } 38 int main() 39 { 40 int i,j,a,b; 41 while(~scanf("%d%d",&n,&k)) 42 { 43 for(i=0;i<n;i++) scanf("%lld",&w[i]); 44 memset(next,-1,sizeof(next)); 45 memset(first,-1,sizeof(first)); 46 for(i=0;i<n-1;i++) 47 { 48 scanf("%d%d",&a,&b); 49 addEdge(a,b,2*i); 50 addEdge(b,a,2*i+1); 51 } 52 memset(son,-1,sizeof(son)); 53 memset(bro,-1,sizeof(bro)); 54 memset(dp,-1,sizeof(dp)); 55 dfs(0,-1); 56 ans=0; 57 for(i=0;i<n;i++) ans=MAX(ans,dptree(i,k)); 58 printf("%lld\n",ans); 59 } 60 return 0; 61 }
WA的代码
1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 101 5 int son[N],bro[N],n,k; 6 int u[2*N],v[2*N],next[2*N],first[N]; 7 long long dp[N][N],w[N],ans; 8 void addEdge(int a,int b,int e) 9 { 10 u[e]=a,v[e]=b; 11 next[e]=first[a]; 12 first[a]=e; 13 } 14 void dfs(int a,int fa) 15 { 16 int e,b; 17 for(e=first[a];e>=0;e=next[e]) 18 { 19 b=v[e]; 20 if(b==fa) continue; 21 if(son[a]==-1) son[a]=b; 22 else bro[b]=bro[son[a]],bro[son[a]]=b; 23 dfs(b,a); 24 } 25 } 26 long long dptree(int a,int k) 27 { 28 int i,ret; 29 if(a<0) return 0; 30 if(dp[a][k]!=-1) return dp[a][k]; 31 if(k==0) return dp[a][k]=0; 32 if(k==1) return dp[a][k]=w[a]; 33 ret=w[a]; 34 if(son[a]==-1) return dp[a][k]=ret; 35 for(i=0;i<k;i++) ret=MAX(ret,w[a]+dptree(son[a],i)+dptree(bro[son[a]],k-1-i)); 36 return dp[a][k]=ret; 37 } 38 int main() 39 { 40 int i,j,a,b; 41 while(~scanf("%d%d",&n,&k)) 42 { 43 for(i=0;i<n;i++) scanf("%lld",&w[i]); 44 memset(next,-1,sizeof(next)); 45 memset(first,-1,sizeof(first)); 46 for(i=0;i<n-1;i++) 47 { 48 scanf("%d%d",&a,&b); 49 addEdge(a,b,2*i); 50 addEdge(b,a,2*i+1); 51 } 52 memset(son,-1,sizeof(son)); 53 memset(bro,-1,sizeof(bro)); 54 memset(dp,-1,sizeof(dp)); 55 dfs(0,-1); 56 ans=0; 57 for(i=0;i<n;i++) ans=MAX(ans,dptree(i,k)); 58 printf("%lld\n",ans); 59 } 60 return 0; 61 }