http://acm.hdu.edu.cn/showproblem.php?pid=6201
n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以在任意城市买书或者卖书,但一次只能买一本和卖一本,一个城市到另一个城市需要花费。问商人最大收益是多少。
方法一(树形dp):
设dp[u][0]表示在以u为根的树中卖一本书获得的最大价值,dp[u][1]表示在以u为根的树中买一本书获得的最大价值。那么在以u为根的子树中能获得的最大价值为max(dp[u][0])+max(dp[u][1]).
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 const int MAXN = 1e5 + 100; 8 typedef pair<int, int> P; 9 vector<P> G[MAXN]; 10 int dp[MAXN][2], ans; 11 int cost[MAXN]; 12 13 void dfs(int u,int pre) 14 { 15 dp[u][0] = cost[u]; 16 dp[u][1] = -cost[u]; 17 for (int i = 0; i < G[u].size(); i++) 18 { 19 int v = G[u][i].first, w = G[u][i].second; 20 if (v == pre) continue; 21 dfs(v, u); 22 dp[u][0] = max(dp[u][0], dp[v][0] - w); 23 dp[u][1] = max(dp[u][1], dp[v][1] - w); 24 } 25 ans = max(ans, dp[u][0] + dp[u][1]); 26 } 27 28 int main() 29 { 30 int T, n,u, v, w; 31 scanf("%d", &T); 32 while (T--) 33 { 34 scanf("%d", &n); 35 for (int i = 1; i <= n; i++) { 36 G[i].clear(); 37 scanf("%d", &cost[i]); 38 } 39 for (int i = 1; i < n; i++) { 40 scanf("%d%d%d", &u, &v, &w); 41 G[u].push_back(P(v, w)); 42 G[v].push_back(P(u, w)); 43 } 44 ans = 0; 45 dfs(1,-1); 46 printf("%d ", ans); 47 } 48 return 0; 49 }