n<=100个点的根为1的二叉树,树边上有苹果,求保留Q<=n条边的最多苹果数。
树形DP,f[i][j]--节点i为根的子树保留j条边最优方案,f[i][0]=0,f[i][j]=max(f[lc[i]][k-1]+f[rc[i]][j-k-1]+v[lc[i]]+v[rc[i]]),这是左右都选的情况,再加只选左只选右方案即可。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<algorithm> 5 //#include<iostream> 6 using namespace std; 7 8 int n,Q; 9 #define maxn 111 10 int f[maxn][maxn]; 11 struct Edge{int to,next,v;}; 12 struct Tree 13 { 14 Edge edge[maxn<<1]; 15 int lc[maxn],rc[maxn],v[maxn]; 16 int first[maxn],le; 17 Tree() {memset(first,0,sizeof(first));le=2;} 18 void in(int x,int y,int v) 19 { 20 edge[le].to=y; 21 edge[le].v=v; 22 edge[le].next=first[x]; 23 first[x]=le++; 24 } 25 void insert(int x,int y,int v) 26 { 27 in(x,y,v); 28 in(y,x,v); 29 } 30 void dfs(int x,int fa) 31 { 32 lc[x]=rc[x]=0; 33 for (int i=first[x];i;i=edge[i].next) 34 if (edge[i].to!=fa) 35 { 36 if (!lc[x]) lc[x]=edge[i].to; 37 else rc[x]=edge[i].to; 38 v[edge[i].to]=edge[i].v; 39 dfs(edge[i].to,x); 40 } 41 } 42 void dp(int x) 43 { 44 if (lc[x]) dp(lc[x]); 45 if (rc[x]) dp(rc[x]); 46 f[x][0]=0; 47 for (int i=1;i<=Q;i++) 48 { 49 f[x][i]=max(f[lc[x]][0]+f[rc[x]][i-1]+v[rc[x]],f[lc[x]][i-1]+f[rc[x]][0]+v[lc[x]]); 50 for (int j=1;j<=i-1;j++) 51 f[x][i]=max(f[x][i],f[lc[x]][j-1]+f[rc[x]][i-j-1]+v[lc[x]]+v[rc[x]]); 52 } 53 } 54 }t; 55 int x,y,v; 56 int main() 57 { 58 scanf("%d%d",&n,&Q); 59 for (int i=1;i<n;i++) 60 { 61 scanf("%d%d%d",&x,&y,&v); 62 t.insert(x,y,v); 63 } 64 t.dfs(1,0); 65 t.dp(1); 66 printf("%d\n",f[1][Q]); 67 return 0; 68 }
时间: 2024-12-29 11:57:58