HDU 6201 树形DP

来源:互联网 发布:红叶知弦小说 编辑:程序博客网 时间:2024/06/11 10:00

题目

transaction transaction transaction

题意

给 n 个点,n-1条边,每个点上图书的价格都不同。 一个商人在则个图上旅游,他将会在一点买一本书,在其中另一点卖掉,问他最多能挣多少钱。(这两个点可重复)

题解

树形 dp。n个点,n-1条边的连通图就是一棵树。开个二维数组dp[MAX][2],dp[i][0]记录在 i 点及 i 的子树买书花费最少值,dp[i][1]记录在 i 点及 i 的子树卖书赚的最大值。dp[i][1] + dp[i][0]则表示经过 i 点进行买卖的利润最大值。遍历 dp 数组找出 max{dp[i][1] + dp[i][0], 1 ≤ i ≤ n} 则为答案。

代码

#include <algorithm>#include <bitset>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <climits>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>using namespace std;const int MAX =  100005;int value[MAX];struct node{    int to,cost;    node(int t = 0,int c = 0) : to(t), cost(c){}};vector<node>nodes[MAX];int dp[MAX][2];int ans = 0;void dfs(int u, int pre) {    dp[u][0] -= value[u];    dp[u][1] += value[u];    for(int i=0;i<nodes[u].size();++i){        int to = nodes[u][i].to;        int cost = nodes[u][i].cost;        if(to == pre)            continue;        dfs(to,u);        dp[u][0] = max(dp[u][0],dp[to][0] - cost);        dp[u][1] = max(dp[u][1],dp[to][1] - cost);    }    ans = max(dp[u][0] + dp[u][1] , ans);}int main(){    int t;    cin >> t;    while(t--){        memset(dp,0,sizeof(dp));        int n;        cin >> n;        for(int i=1;i<=n;++i){            nodes[i].clear();        }        for(int i=1;i<=n;++i){            scanf("%d",value + i);        }        int x,y,z;        for(int i=0;i<n-1;++i){            scanf("%d %d %d",&x,&y,&z);            nodes[x].push_back(node(y,z));            nodes[y].push_back(node(x,z));        }        ans = 0;        dfs(1,-1);        cout << ans <<endl;    }    return 0;}