hdu1561 树形dp+背包(攻打某点必须要攻打上司点,问攻打最多m点所获得的收益)
有一个技巧如何把森林转化成树?把所有无根点连向一个统一的根。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int now,m,head[205],next[205],point[205],dp[205][205]; 6 void add(int x,int y) 7 { 8 next[++now]=head[x]; 9 head[x]=now; 10 point[now]=y; 11 } 12 void dfs(int pre,int u) 13 { 14 int i,x,y,v; 15 for (i=head[u];i!=-1;i=next[i]) 16 { 17 v=point[i]; 18 if (v==pre) continue; 19 dfs(u,v); 20 for (x=m+1;x>=2;x--) 21 for (y=1;y<x;y++) 22 dp[u][x]=max(dp[u][x],dp[u][y]+dp[v][x-y]); 23 } 24 } 25 int main() 26 { 27 int n,i,a,b; 28 while (~scanf("%d%d",&n,&m)&&(n||m)) 29 { 30 memset(head,-1,sizeof(head)); 31 memset(dp,0,sizeof(dp)); 32 now=0; 33 for (i=1;i<=n;i++) 34 { 35 scanf("%d%d",&a,&b); 36 add(a,i); 37 dp[i][1]=b; 38 } 39 dfs(-1,0); 40 printf("%d\n",dp[0][m+1]); 41 } 42 return 0; 43 }