xdoj 1070 Eddy’s network system(简单树dp)

n个节点的树中选出m个点的子树,使子树的点权和最大。

树背包模板题。合并子树的时候枚举到子树大小就够了,这样保证每个点被,是O(n^2)的。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define inc(i,n) for (int i=0;i<n;i++)
  5. #define dec(i,n) for (int i=n-1;i>=0;i--)
  6. int a[110][110];
  7. vector<int> ed[110];
  8. int n,m; 
  9. void dfs(int u, int f){
  10. 	for (int i=0;i<ed[u].size();i++){
  11. 		int v=ed[u][i];
  12. 		if (v^f){
  13. 			dfs(v,u);
  14. 			dec(j,n+1){
  15. 				inc(k,j)
  16. 				a[u][j]=max(a[u][j],a[u][j-k]+a[v][k]);
  17. 			}
  18. 		}
  19. 	}
  20. }
  21.  
  22. int main(){
  23. 	int T; cin>>T;
  24. 	while (T--){
  25. 		memset(a,0xC0,sizeof a);
  26. 		cin>>n>>m; 
  27. 		inc(i,n) scanf("%d",a[i]+1),ed[i].clear();
  28. 		inc(i,n-1){
  29. 			int x,y; scanf("%d%d",&x,&y);
  30. 			ed[x].push_back(y);
  31. 			ed[y].push_back(x);
  32. 		}
  33. 		dfs(0,-1);
  34. 		int ans=0;
  35. 		inc(i,n) ans=max(ans,a[i][m]);
  36. 		cout<<ans<<'\n';
  37. 	}
  38. 	return 0;
  39. }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注