HDU 6201 transaction transaction transaction(树形DP)
2018-02-14 16:35
381 查看
Description
给出一棵nn个节点的树,一个人要在一个节点买一本书然后走到另一个节点卖掉,在第ii个节点买卖书的价格为valivali,经过每条边都要付出对应的代价,问这个人赢利的最大值
Input
第一行一正整数TT表示用例组数,每组用例首先输入一正整数nn表示点数,之后输入nn个整数valivali表示ii节点买卖书的价格,之后n−1n−1行每行输入三个整数u,v,wu,v,w表示u,vu,v之间有一条经过代价为ww的边(1≤T≤10,2≤n≤105,1≤vali≤104,1≤w≤104)(1≤T≤10,2≤n≤105,1≤vali≤104,1≤w≤104)
Output
输出最大赢利
Sample Input
1
4
10 40 15 30
1 2 30
1 3 2
3 4 10
Sample Output
8
Solution
以dp[u][0/1]dp[u][0/1]表示在以uu为根的子树中买/卖一本书的最大利润,则答案即为max(dp[u][0]+dp[u][1]),1≤u≤nmax(dp[u][0]+dp[u][1]),1≤u≤n
且有转移dp[u][0]=max(−valu,dp[v][0]−w(u,v)),dp[u][1]=max(valu,dp[v][1]−w(u,v))dp[u][0]=max(−valu,dp[v][0]−w(u,v)),dp[u][1]=max(valu,dp[v][1]−w(u,v)),其中vv是uu的儿子节点,w(u,v)w(u,v)表示树边u↔vu↔v的权值
Code
给出一棵nn个节点的树,一个人要在一个节点买一本书然后走到另一个节点卖掉,在第ii个节点买卖书的价格为valivali,经过每条边都要付出对应的代价,问这个人赢利的最大值
Input
第一行一正整数TT表示用例组数,每组用例首先输入一正整数nn表示点数,之后输入nn个整数valivali表示ii节点买卖书的价格,之后n−1n−1行每行输入三个整数u,v,wu,v,w表示u,vu,v之间有一条经过代价为ww的边(1≤T≤10,2≤n≤105,1≤vali≤104,1≤w≤104)(1≤T≤10,2≤n≤105,1≤vali≤104,1≤w≤104)
Output
输出最大赢利
Sample Input
1
4
10 40 15 30
1 2 30
1 3 2
3 4 10
Sample Output
8
Solution
以dp[u][0/1]dp[u][0/1]表示在以uu为根的子树中买/卖一本书的最大利润,则答案即为max(dp[u][0]+dp[u][1]),1≤u≤nmax(dp[u][0]+dp[u][1]),1≤u≤n
且有转移dp[u][0]=max(−valu,dp[v][0]−w(u,v)),dp[u][1]=max(valu,dp[v][1]−w(u,v))dp[u][0]=max(−valu,dp[v][0]−w(u,v)),dp[u][1]=max(valu,dp[v][1]−w(u,v)),其中vv是uu的儿子节点,w(u,v)w(u,v)表示树边u↔vu↔v的权值
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; typedef pair<int,int>P; const int INF=0x3f3f3f3f,maxn=100005; int T,n,val[maxn],dp[maxn][2],ans; vector<P>g[maxn]; void dfs(int u,int fa) { dp[u][0]=-val[u],dp[u][1]=val[u]; for(int i=0;i<g[u].size();i++) { int v=g[u][i].first,w=g[u][i].second; if(v==fa)continue; dfs(v,u); dp[u][0]=max(dp[u][0],dp[v][0]-w); dp[u][1]=max(dp[u][1],dp[v][1]-w); } 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",&val[i]),g[i].clear(); for(int i=1;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); g[x].push_back(P(y,z)),g[y].push_back(P(x,z)); } ans=0; dfs(1,1); printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 6201 transaction transaction transaction (树形DP)
- HDU 6201 transaction transaction transaction (树形dp)
- HDU 6201 transaction transaction transaction【树形DP||SPFA最长路】
- HDU-6201 transaction transaction transaction(树形dp)
- 2017沈阳网络赛 1008 HDU 6201 transaction transaction transaction(树形dp)
- HDU 6201 transaction transaction transaction(树形DP)
- HDU 6201 transaction transaction transaction(树形dp)
- HDU 6201 树形DP 或 最长路
- HDU-6201 transaction transaction transaction(树dp / 最长(短)路)
- HDU沈阳网络赛:transaction transaction transaction(树形dp & 最短路)
- HDU 6201 transaction transaction transaction dp
- HDU 6201 树形dp
- HDU 6201 transaction transaction transaction(dp)
- HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
- HDU 6201 transaction transaction transaction (树形DP or 拆点最短路)
- hdu 6201 transaction transaction transaction tree dp
- HDU 6201 树形DP
- 【转】HDU 6201 树形DP 或 最长路
- hdu-1561 The more, The Better (树形dp入门,有依赖的背包问题
- hdu 4616 Game 树形dp