標籤:std void dev print main mem 保留 first scan
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 11110 int f[maxn][maxn];11 struct Edge{int to,next,v;};12 struct Tree13 {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 }
View Code
CODEVS5565 二叉蘋果樹