ZOJ2111 HDU1011 Starship Troopers, 树形DP

来源:互联网 发布:手机维修网络培训 编辑:程序博客网 时间:2024/05/04 20:38

经典的树形DP题, 题解请看代码中的注释


/******************************************************************************* # Author : Neo Fung # Email : neosfung@gmail.com # Last modified: 2012-02-03 18:04 # Filename: ZOJ2111 HDU1011 Starship Troopers.cpp # Description : 树形DP. dp[x][y]表示的是在x点放置y人可以获得多少最多的brain. 切记哪怕经过的点没有bug, 都需要放置人 ******************************************************************************/#ifdef _MSC_VER#define DEBUG#endif#include <fstream>#include <stdio.h>#include <iostream>#include <string.h>#include <string>#include <limits.h>#include <algorithm>#include <math.h>#include <numeric>#include <functional>#include <ctype.h>#include <vector>#define MAX 110using namespace std;vector<int> vec[MAX];int bugs[MAX],brains[MAX];bool visited[MAX];int dp[MAX][MAX];void init(const int &n){memset(visited,false,sizeof(visited));memset(dp,0,sizeof(dp));for(int i=0;i<=n;++i){vec[i].clear();}}void add(const int &x,const int &y){vec[x].push_back(y);vec[y].push_back(x);}void dfs(const int &u, int m){visited[u]=true;  int t=(bugs[u]+19)/20;   for(int i=t;i<=m;++i)    dp[u][i]=brains[u];for(size_t i=0;i<vec[u].size();++i){int v=vec[u][i];if(!visited[v]){dfs(v,m);      // 假如到达节点 u 的有 j 人(j>=t),      // 如果到达后继节点 v 的有k人, 则留在u的有j-k人      // 则对于任一节点有dp[u][j]=max{dp[u][j-k]+dp[v][k]};       for(int j=m;j>t;--j)for(int k=1;j-k>=t;++k)dp[u][j] = max(dp[u][j],dp[u][j-k]+dp[v][k]);}}}int main(void){#ifdef DEBUG    freopen("../stdin.txt","r",stdin);  freopen("../stdout.txt","w",stdout); #endif    int n,m,x,y;  while(~scanf("%d%d",&n,&m)&& !(n==-1&&m==-1))  {  init(n);  for(int i=1;i<=n;++i)  scanf("%d%d",&bugs[i],&brains[i]);  for(int i=1;i<n;++i)  {  scanf("%d%d",&x,&y);  add(x,y);  }    if(m==0)    {      printf("0\n");      continue;    }  dfs(1,m);  printf("%d\n",dp[1][m]);  }  return 0;}


原创粉丝点击