题目描述
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
dp[i][j][0]表示到第i个结点分了j段,折弯下去的状态最大值。
dp[i][j][1]表示到第i个结点分了j段伸上去的状态的最大值。
对于每一个结点0+0,0+1,1+0,1+1,这四种情况0带表子节点折返下去,1代表伸上去
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int N=410000;
vector<ll>go[N<<1];
ll n;
ll w[N],dp[N][4][2];
void treedp(ll k1,ll k2)
{
ll f[4][3];//临时
ll pre[4][3];
memset(f,0x00,sizeof f );
for(int i=0;i<go[k1].size();i++)
{
ll j=go[k1][i];
if(j!=k2)
{
treedp(j,k1);
memcpy(pre,f,sizeof f);
for(int a=0;a<=3;a++)
{
for(int b=0;b<=3;b++)
{
for(int c=0;c<=2;c++)
{
for(int d=0;d<=1;d++)
{
if(a+b>3 || c+d>2) continue;
f[a+b][c+d]=max(f[a+b][c+d],pre[a][c]+dp[j][b][d]);
}
}
}
}
}
}
for (int i=0;i<4;i++)
{
dp[k1][i][0]=max(dp[k1][i][0],f[i][0]);
dp[k1][i][1]=max(dp[k1][i][1],f[i][1]+w[k1]);
if (i<3)
{
for (int a=0;a<2;a++)
for (int b=a+1;b<3;b++)
dp[k1][i+1][a]=max(dp[k1][i+1][a],f[i][b]+w[k1]);//包含0+0,0+1,1+0,1+1,其中1+1表示连成弯曲的折返子树的情况
}
}
}
int main()
{
memset(dp,0,sizeof(dp));
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
for(int i=1;i<n;i++)
{
ll k1,k2;
scanf("%lld%lld",&k1,&k2);
go[k1].push_back(k2);
go[k2].push_back(k1);
}
treedp(1,0);
ll ans=0;
for(int i=0;i<=3;i++) ans=max(ans,dp[1][i][0]);
cout<<ans<<endl;
}
/*
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
*/