hdoj 5834 Magic boy Bi Luo with his excited tree 树形dp
发布时间:2020-12-14 01:36:32 所属栏目:大数据 来源:网络整理
导读:假设 1 为 根节点 dp[i][0] 代表从自己出发选择到儿子节点最后必须返回自己的最大价值 dp[i][1] 代表从自己出发选择到儿子节点最后可选择不回来的最大价值 并记录最后选择的离开节点 id[i] 树形dp先跑一遍出来 再第二遍 dfs 因为每个节点也可以流向父节点所
假设 1 为 根节点 再第二遍 dfs 因为每个节点也可以流向父节点所以要合并 #include<cstdio>
#include<algorithm>
#include<iostream>
#define maxn 110005
using namespace std;
int dp[maxn][3],ans[maxn],va[maxn];
int cost[2*maxn],Next[2*maxn],last[2*maxn],e[2*maxn],l,n,id[maxn];
void add(int a,int b,int C)
{
e[l] = b;
cost[l] = C;
Next[l] = last[a];
last[a] = l;
l++;
}
void dfs1(int pre,int fa)
{
dp[pre][0] = va[pre];
dp[pre][1] = va[pre];
id[pre] = -1;
for(int i = last[pre]; i!=-1; i = Next[i])
{
int v = e[i];
if(v == fa)continue;
dfs1(v,pre);
int tem = max(0,dp[v][0] - 2 * cost[i]);
int tem2 = max(0,dp[v][1] - cost[i]);
dp[pre][1] = dp[pre][1] +tem;
if(dp[pre][0] + tem2 > dp[pre][1])
{
dp[pre][1] = dp[pre][0] + tem2;
id[pre] = v;
}
dp[pre][0] += tem;
}
}
void dfs2(int pre,int fa,int sum1,int sum2)
{
int sum11 = dp[pre][0];
int sum22 = dp[pre][1];
ans[pre] = max(sum2 + sum11,sum1 + sum22);
sum22 += sum1;
if(sum11 + sum2 > sum22)
{
sum22 = sum11 + sum2;
id[pre] = fa;
}
sum11 += sum1;
for(int i = last[pre]; i!=-1; i = Next[i])
{
int v = e[i];
if(v == fa)continue ;
if(v == id[pre])
{
int sum11 = sum1 + va[pre],sum22 = sum2 + va[pre];
for(int j = last[pre]; j != -1 ;j = Next[j])
{
int vv = e[j];
if(vv == v || vv == fa)continue ;
int temp = max(0,dp[vv][0] - cost[j]*2);
sum22 = max(sum11 + max(0,dp[vv][1] - cost[j]),sum22 + temp);
sum11 += temp;
}
sum11 = max(0,sum11 - 2*cost[i]);
sum22 = max(0,sum22 - cost[i]);
dfs2(v,pre,sum11,sum22);
}
else{
int temp1 = max(0,dp[v][0] - 2 * cost[i]);
int temp2 = max(0,sum11 - temp1 - 2 * cost[i]);
int temp3 = max(0,sum22 - temp1 - cost[i]);
dfs2(v,temp2,temp3);
}
}
}
int main()
{
int t,i1 = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0; i <=n; i++) last[i] = -1;
l = 0;
for(int i = 1; i <= n; i++) scanf("%d",&va[i]);
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,c);
add(b,a,c);
}
dfs1(1,-1);
dfs2(1,-1,0,0);
printf("Case #%d:n",i1);
i1++;
for(int i = 1; i <= n; i++)
printf("%dn",ans[i]);
}
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |