ICPC2017网络赛(沈阳)1008 transaction transaction transaction——树形DP
原创
©著作权归作者所有:来自51CTO博客作者软糖酱八号机的原创作品,请联系作者获取转载授权,否则将追究法律责任
HDU 6201
Kelukin is a businessman. Every day, he travels around cities to do some business. On August 17th, in memory of a great man, citizens will read a book named "the Man Who Changed China". Of course, Kelukin wouldn't miss this chance to make money, but he doesn't have this book. So he has to choose two city to buy and sell.
As we know, the price of this book was different in each city. It is ai yuan in it city. Kelukin will take taxi, whose price is 1yuan per km and this fare cannot be ignored.
There are n−1 roads connecting n cities. Kelukin can choose any city to start his travel. He want to know the maximum money he can get.
定义dp[i][j]为第i个城市【从它的子树中】买(0)或者卖(1)书所得的最大利润
状态转移方程为:
dp[u][0] = max(dp[u][0], dp[v][0] - cost);
dp[u][1] = max(dp[u][1], dp[v][1] - cost);
求解ans只要:
ans = max(ans, dp[u][0] + dp[u][1]);
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
typedef pair<int, int> P;
using namespace std;
const int maxn = 1e5 + 10;
int T, n, ans, a[maxn], dp[maxn][2];
vector<P> G[maxn];
void dfs(int u, int par) {
dp[u][0] = -a[u], dp[u][1] = a[u];
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].first, cost = G[u][i].second;
if (v == par) continue;
dfs(v, u);
dp[u][0] = max(dp[u][0], dp[v][0] - cost);
dp[u][1] = max(dp[u][1], dp[v][1] - cost);
}
ans = max(ans, dp[u][0] + dp[u][1]);
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); G[i].clear(); }
for (int i = 1; i <= n - 1; i++) {
int u, v, cost; scanf("%d %d %d", &u, &v, &cost);
G[u].push_back(make_pair(v, cost)), G[v].push_back(make_pair(u, cost));
}
ans = 0; dfs(1, -1);
printf("%d\n", ans);
}
return 0;
}