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 }

 

posted @ 2012-12-11 15:11  浙西贫农  阅读(144)  评论(0编辑  收藏  举报