poj 1155 树形背包
http://blog.csdn.net/libin56842/article/details/9908199
树形背包:
首先是建树,每个结构体为一个节点,包括下一个点序号,值,和next。
tree[ptr]会保存所有的节点序列,而head数组则是保存每个节点的最后一个子节点在序列中的位置,next则是保存上一个子节点在序列中的位置,若没有则为-1。
遍历时从i=head[root]出发,到i=-1结束,不断往子节点遍历,同一层之间用next遍历,就可以遍历树的所有节点。
树状dp。由于求的是最多多少用户,那么我们可以把用户个数当成一个状态。dp[i][j]代表i节点为根节点的子树j个用户的时候最大剩余费用。
则dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]-w[i][son]);
注意两点,第一点是上面式子中的dp[i][k]必须先用一个tem[MAX]数组提取出来,因为在计算的过程中会相互影响。第二点是价值可能是负值,所以dp初始化的时候要初始化为负的最大值。
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <cctype> #include <vector> #include <iterator> #include <set> #include <map> #include <sstream> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define spf sprintf #define pb push_back #define debug printf("!\n") #define MAXN 1010 #define MAX(a,b) a>b?a:b #define blank pf("\n") #define LL long long #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define pqueue priority_queue #define INF 0x3f3f3f3f int n,m; struct node { int y,val,next; }tree[9005]; int head[3005],dp[3005][3005],num[3005],tem[3005],ptr=1; void add(int x,int y,int val) { tree[ptr].y = y; tree[ptr].val = val; tree[ptr].next = head[x]; head[x] = ptr++; } void dfs(int root) { int i,j,k; for(i=head[root]; i!=-1; i=tree[i].next) { int p = tree[i].y; dfs(p); for(j=0;j<=num[root];j++) tem[j] = dp[root][j]; for(j=0;j<=num[root];j++) { for(k=1;k<=num[p];k++) { dp[root][k+j] = max(dp[root][j+k],tem[j]+dp[p][k]-tree[i].val); //pf("%d %d %d %d\n",root,j,k,dp[root][j+k]); } } num[root]+=num[p]; } } int main() { int i,j,k,a,b; while(~sf("%d%d",&n,&m) && m+n) { mem(head,-1); for(i=1;i<=n-m;i++) { sf("%d",&k); num[i] = 0; for(j=0;j<k;j++) { sf("%d%d",&a,&b); add(i,a,b); } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) dp[i][j] = -10000000; } for(i=n-m+1;i<=n;i++) { num[i] = 1; sf("%d",&dp[i][1]); } dfs(1); for(i=m;i>=0;i--) { if(dp[1][i]>=0) { pf("%d\n",i); break; } } } return 0; }