hdoj 5834 Magic boy Bi Luo with his excited tree 树形dp
发布时间:2021-01-27 04:30:20 所属栏目:大数据 来源:网络整理
导读:假设 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; } (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |