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.
Input
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.
Output
Print one integer denoting the answer.
Example
Input
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
Output
110
求一棵树中三条不相交的路径的最大权值和
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+9;
long long val[maxn];
vector<long long>edge[maxn];
long long dp[maxn][5][2];
void bfs(long long x,long long fa)
{
long long son[5][3];
long long tmp[5][3];
long long ans[5][3];
memset(ans,0,sizeof(ans));
memset(tmp,0,sizeof(tmp));
memset(son,0,sizeof(son));//
for(long long ii = 0; ii<edge[x].size(); ii++)
{
long long to = edge[x][ii];
if(to==fa)
continue;
bfs(to,x);
for(long long i = 0; i<=3; i++)
{
son[i][0] = dp[to][i][0];
son[i][1] = dp[to][i][1];
}
printf("%lld:\n",x);
for(long long i = 0; i<=3; i++)
{
for(long long j = 0; j+i<=3; j++)
{
for(long long k = 0; k<=2; k++)
{
for(long long l = 0; k+l<=2; l++)
{
//因为son[i][0]和son[i][1]中会有相交的部分,所以必须只用上一步得到的ans和当前的son[i][j]进行更新(不能自身更新自身),用tmp保存下来,最后在复制到ans
tmp[i+j][k+l] = max(tmp[i+j][k+l],son[i][k]+ans[j][l]);
}
}
}
}
memcpy(ans,tmp,sizeof(ans));
//ans[i][j]表示当前节点的子树有i条链不必以其子节点为端点(可以可不以),有j条链以其子节点为端点的最大权值
}
for(long long i = 0; i<=3; i++)
{
for(long long j = 0; j<=2; j++)
{
printf("ans[%lld][%lld] = %lld\n",i,j,ans[i][j]);
}
}
//求dp[x][i][0],当前节点可以是一条链的端点,也可以不是
for(long long i = 0; i<=3; i++) //由其子树构成i条链的最大值(不含当前节点)
{
dp[x][i][0] = ans[i][0];
}
for(long long i = 1; i<=3; i++)//加上当前节点,所构成的i条链的最大值
{
for(long long j = 0; j<=2; j++)
{
//j=0时,当前节点是与其它链不相交的一条单独的链
//j=1时,当前节点并上以其子节点为终端的一条链
//j=2时,当前节点连接两条以其两个子节点为终端的链,使其成为一条链
dp[x][i][0] =max(dp[x][i][0],ans[i-1][j]+val[x]);
}
}
//求dp[x][i][1],当前节点必须是一条链的端点
for(long long i = 0; i<=3; i++)
{
for(long long j = 0; j<=1; j++)
{
//j=0时,当前节点是与其它链不相交的一条单独的链
//j=1时,当前节点并上以其子节点为终端的一条链
dp[x][i][1] = max(dp[x][i][1],ans[i][j]+val[x]);
}
}
for(long long i = 0; i<=3; i++)
{
printf("dp[%lld][%lld][0] = %lld\n",x,i,dp[x][i][0]);
printf("dp[%lld][%lld][1] = %lld\n",x,i,dp[x][i][1]);
}
}
int main()
{
long long i,j,m,n,a,b;
ios::sync_with_stdio(false);
cin>>n;
for(i = 1; i<=n; i++)
{
cin>>val[i];
}
for(i = 1; i<n; i++)
{
cin>>a>>b;
edge[a].push_back(b);
edge[b].push_back(a);
}
bfs(1,0);
cout<<dp[1][3][0]<<endl;
return 0;
}