先建樹,以0爲根,把入度爲0的點都與建邊。此題建單向邊便可。ios
狀態方程:dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][j])ide
方程很好想,dp的初始化和進行揹包是卻是用很長的時間。spa
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 using namespace std; 6 const int N=205; 7 int dp[N][N]; 8 vector<int>V[N]; 9 int val[N]; 10 void init() 11 { 12 memset(dp,0,sizeof(dp)); 13 for(int i=0;i<N;i++) V[i].clear(); 14 } 15 void dfs(int u,int c) 16 { 17 int i; 18 dp[u][1]=val[u];//for(i=1;i<=c;i++) dp[u][i]=val[u]; 19 for(i=0;i<(int)V[u].size();i++) 20 { 21 int v=V[u][i]; 22 dfs(v,c-1); 23 for(int j=c;j>=1;j--) 24 for(int k=1;j-k>=1;k++) 25 dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]); 26 // for(int j=c;j>=1;j--) 27 // printf("[%d] [%d] -->%d\n",u,j,dp[u][j]); 28 } 29 } 30 int main() 31 { 32 //freopen("Input.txt","r",stdin); 33 int n,m,i; 34 while(~scanf("%d%d",&n,&m)) 35 { 36 if(n==0&&m==0) break; 37 init(); 38 int a,b; 39 for(i=1;i<=n;i++) 40 { 41 scanf("%d%d",&a,&b); 42 val[i]=b; 43 V[a].push_back(i); 44 } 45 dfs(0,m+1); 46 printf("%d\n",dp[0][m+1]); 47 } 48 }