ZOJ 3626 Treasure Hunt I
刷水题,贴代码。比较裸的树形DP。。dp(i,j)表示以i节点为根节点用j天时间能够获得的最大价值。由于要往返,m除以2就可以了。
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define maxn 101 5 using namespace std; 6 int n,m,start,e; 7 int dp[maxn][maxn],next[maxn << 1],v[maxn << 1],cost[maxn << 1],first[maxn],visit[maxn],val[maxn]; 8 9 inline int max(int a,int b) 10 { 11 return a > b ? a : b; 12 } 13 void add_edge(int a,int b,int c) 14 { 15 cost[e] = c; 16 v[e] = b; 17 next[e] = first[a]; 18 first[a] = e; 19 e++; 20 } 21 22 void read_graph() 23 { 24 e = 0; 25 memset(first,-1,sizeof(first)); 26 memset(visit,0,sizeof(visit)); 27 int i,j,a,b,c; 28 for(i = 1;i <= n;i++) 29 scanf("%d",&val[i]); 30 31 for(i = 1;i < n;i++) 32 { 33 scanf("%d%d%d",&a,&b,&c); 34 add_edge(a,b,c); 35 add_edge(b,a,c); 36 } 37 scanf("%d%d",&start,&m); 38 m /= 2; 39 for(i = 1;i <= n;i++) 40 for(j = 0;j <= m;j++) 41 dp[i][j] = val[i]; 42 } 43 44 void dfs(int u) 45 { 46 visit[u] = 1; 47 int i,j,k,x; 48 for(i = first[u];i != -1;i = next[i]) 49 { 50 x = v[i]; 51 if(visit[x]) continue; 52 dfs(x); 53 for(j = m;j >= cost[i];j--) 54 for(k = 0;k <= j - cost[i];k++) 55 dp[u][j] = max(dp[u][j],dp[u][j - cost[i] - k] + dp[x][k]); 56 } 57 } 58 int main() 59 { 60 while(scanf("%d",&n) == 1) 61 { 62 read_graph(); 63 dfs(start); 64 printf("%d\n",dp[start][m]); 65 } 66 return 0; 67 }