時間限制:C/C++ 2秒,其他語言4秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
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.
示例1
輸入
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
題意:在樹上找3條不相交鏈,要求鏈上權值和最大
題解:樹型dp,設dp[u][j][k]:以u爲頂點的子樹上有j條不相交鏈,k=0表示頂點不可被父節點連接,k=1表示頂點可被父節點連接。一堆轉移方程,寫的時候漏掉好幾個,WA到想吐血系列。。。
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MX = 1e6 + 5;
struct Edge {
int v, nxt;
} E[MX * 2];
int head[MX], tot;
void init (int n) {
for (int i = 1; i <= n; i++) head[i] = -1;
tot = 0;
}
void edge_add (int u, int v) {
E[tot] = (Edge) {v, head[u]}; head[u] = tot++;
}
int a[MX];
LL dp[MX][4][2], t[MX][4][2];
inline LL Max (LL d[2]) {
return max (d[0], d[1]);
}
void dfs (int u, int pre) {
memset (dp[u], 0, sizeof (dp[u]) );
memset (t[u], 0, sizeof (t[u]) );
dp[u][1][1] = a[u];
for (int i = head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if (v == pre) continue;
dfs (v, u);
dp[u][3][0] = max (dp[u][3][0], Max (dp[v][3]) );
dp[u][3][0] = max (dp[u][3][0], Max (dp[v][2]) + Max (t[u][1]) );
dp[u][3][0] = max (dp[u][3][0], Max (dp[v][1]) + Max (t[u][2]) );
dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][1][1] + dp[v][3][1]);
dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][2][1] + dp[v][2][1]);
dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][3][1] + dp[v][1][1]);
dp[u][3][0] = max (dp[u][3][0], dp[u][2][0] + Max (dp[v][1]) );
dp[u][3][0] = max (dp[u][3][0], dp[u][1][0] + Max (dp[v][2]) );
dp[u][3][1] = max (dp[u][3][1], a[u] + dp[v][3][1]);
dp[u][3][1] = max (dp[u][3][1], a[u] + max (dp[v][2][1] + Max (t[u][1]), Max (dp[v][2]) + t[u][1][1]) );
dp[u][3][1] = max (dp[u][3][1], a[u] + max (dp[v][1][1] + Max (t[u][2]), Max (dp[v][1]) + t[u][2][1]) );
dp[u][3][1] = max (dp[u][3][1], a[u] + Max (dp[v][2]) );
dp[u][3][1] = max (dp[u][3][1], a[u] + Max (dp[v][1]) + Max (t[u][1]) );
dp[u][2][0] = max (dp[u][2][0], Max (dp[v][2]) );
dp[u][2][0] = max (dp[u][2][0], Max (dp[v][1]) + Max (t[u][1]) );
dp[u][2][0] = max (dp[u][2][0], a[u] + t[u][1][1] + dp[v][2][1]);
dp[u][2][0] = max (dp[u][2][0], a[u] + t[u][2][1] + dp[v][1][1]);
dp[u][2][0] = max (dp[u][2][0], dp[u][1][0] + Max (dp[v][1]) );
dp[u][2][1] = max (dp[u][2][1], a[u] + dp[v][2][1]);
dp[u][2][1] = max (dp[u][2][1], a[u] + max (dp[v][1][1] + Max (t[u][1]), Max (dp[v][1]) + t[u][1][1]) );
dp[u][2][1] = max (dp[u][2][1], a[u] + Max (dp[v][1]) );
dp[u][1][0] = max (dp[u][1][0], Max (dp[v][1]) );
dp[u][1][0] = max (dp[u][1][0], a[u] + dp[v][1][1] + t[u][1][1]);
dp[u][1][1] = max (dp[u][1][1], a[u] + dp[v][1][1]);
t[u][3][0] = max (t[u][3][0], Max (dp[v][3]) );
t[u][3][0] = max (t[u][3][0], Max (dp[v][2]) + Max (t[u][1]) );
t[u][3][0] = max (t[u][3][0], Max (dp[v][1]) + Max (t[u][2]) );
t[u][3][1] = max (t[u][3][1], dp[v][3][1]);
t[u][3][1] = max (t[u][3][1], max (dp[v][2][1] + Max (t[u][1]), Max (dp[v][2]) + t[u][1][1]) );
t[u][3][1] = max (t[u][3][1], max (dp[v][1][1] + Max (t[u][2]), Max (dp[v][1]) + t[u][2][1]) );
t[u][2][0] = max (t[u][2][0], Max (dp[v][2]) );
t[u][2][0] = max (t[u][2][0], Max (dp[v][1]) + Max (t[u][1]) );
t[u][2][1] = max (t[u][2][1], dp[v][2][1]);
t[u][2][1] = max (t[u][2][1], max (dp[v][1][1] + Max (t[u][1]), Max (dp[v][1]) + t[u][1][1]) );
t[u][1][0] = max (t[u][1][0], Max (dp[v][1]) );
t[u][1][1] = max (t[u][1][1], dp[v][1][1]);
}
}
int main() {
int n;
//freopen ("in.txt", "r", stdin);
while (~scanf ("%d", &n) ) {
init (n);
for (int i = 1; i <= n; i++) scanf ("%d", &a[i]);
for (int i = 1; i < n; i++) {
int u, v;
scanf ("%d%d", &u, &v);
edge_add (u, v);
edge_add (v, u);
}
dfs (1, -1);
printf ("%lld\n", Max (dp[1][3]) );
}
return 0;
}