时间限制: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;
}