牛客國慶集訓派對Day2: H. travel(樹形線頭DP)
阿新 • • 發佈:2018-11-23
連結:https://ac.nowcoder.com/acm/contest/140/H
來源:牛客網
題目描述
White Cloud has a tree with n nodes.The root is a node with number 1. Each node has a value.
White Rabbit wants to travel in the tree 3 times. In Each travel it will go through a path in the tree.
White Rabbit can't pass a node more than one time during the 3 travels. It wants to know the maximum sum value of all nodes it passes through.
輸入描述:
The first line of input contains an integer n(3 <= n <= 400001) In the next line there are n integers in range [0,1000000] denoting the value of each node. For the next n-1 lines, each line contains two integers denoting the edge of this tree.
輸出描述:
Print one integer denoting the answer.
輸入
13 10 10 10 10 10 1 10 10 10 1 10 10 10 1 2 2 3 3 4 4 5 2 6 6 7 7 8 7 9 6 10 10 11 11 12 11 13
輸出
110
題意:
給你一棵n個節點的樹,每個點都有一個權值,選出三條不相交路徑使得權值和最大
思路:
dp[i][j][0]表示以i為根的子樹選了j條路徑的最大權值和
dp[i][j][1]表示以i為根的子樹選了j條路徑,其中一條路徑的一端為i的最大權值和
那麼dp時來一波類似於揹包的轉移就好了
//https://ac.nowcoder.com/acm/contest/140/H #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 vector<int> G[500005]; int val[500005]; LL dp[500005][5][2]; void Sech(int u, int fa) { int i, j, p, q, v, t; LL now[5][4], c[5][4], sum[5][4]; memset(now, 0, sizeof(now)); for(t=0;t<G[u].size();t++) { v = G[u][t]; if(v==fa) continue; Sech(v, u); memset(c, 0, sizeof(c)); for(i=0;i<=3;i++) c[i][0] = dp[v][i][0], c[i][1] = dp[v][i][1]; memset(sum, 0, sizeof(sum)); for(i=0;i<=3;i++) { for(j=0;i+j<=3;j++) { for(p=0;p<=2;p++) { for(q=0;p+q<=2;q++) sum[i+j][p+q] = max(sum[i+j][p+q], now[i][p]+c[j][q]); } } } memcpy(now, sum, sizeof(now)); } for(i=0;i<=3;i++) dp[u][i][0] = now[i][0]; for(i=0;i<=2;i++) { for(j=0;j<=2;j++) dp[u][i+1][0] = max(dp[u][i+1][0], now[i][j]+val[u]); } for(i=0;i<=3;i++) { for(j=0;j<=1;j++) dp[u][i][1] = max(dp[u][i][1], now[i][j]+val[u]); } } int main(void) { int n, i, x, y; scanf("%d", &n); for(i=1;i<=n;i++) scanf("%d", &val[i]); for(i=1;i<=n-1;i++) { scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } Sech(1, 0); printf("%lld\n", dp[1][3][0]); return 0; }