题意

分析

考场做法

一眼看出是支持换根的树形dp。

用\(f(x,0/1)\)表示x及其子树中,从x出发,不一定/一定回到x的最大收益。

然后子树很好做。

换根的时候,我先计算后还原,需要考虑很多,调了很久。

后来知道可以用up,down状态转移,会好写一些,但要考虑得跟我先前打的差不多。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#include<cassert>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read()
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return data*w;
}
template<class T> il T read(T&x)
{
return x=read<T>();
}
typedef long long ll;
const int INF=0x7fffffff; co int MAXN=3e5+7; struct Edge
{
int nx,to,w;
}E[MAXN<<1];
int head[MAXN],ecnt; il void addedge(rg int x,rg int y,rg int w)
{
E[++ecnt].to=y,E[ecnt].w=w;
E[ecnt].nx=head[x],head[x]=ecnt;
} int fa[MAXN],fw[MAXN];
int val[MAXN]; ll f[MAXN][2];
int maxv[MAXN],secv[MAXN]; il ll take(rg int y)
{
return max(0LL,f[y][0]-fw[y]);
} il ll fetch(rg int y)
{
return max(0LL,f[y][1]-2*fw[y]);
} il ll calc(rg int y)
{
return take(y)-fetch(y);
} il void dfs1(rg int x,rg int fath)
{
fa[x]=fath;
f[x][1]=val[x];
for(rg int i=head[x];i;i=E[i].nx)
{
rg int y=E[i].to,w=E[i].w;
if(y==fath)
{
fw[x]=w;
continue;
}
dfs1(y,x);
f[x][1]+=fetch(y);
}
f[x][0]=f[x][1];
for(rg int i=head[x];i;i=E[i].nx)
{
rg int y=E[i].to;
if(y==fath)
continue;
if(calc(y)>calc(secv[x]))
{
secv[x]=y;
if(calc(secv[x])>calc(maxv[x]))
swap(secv[x],maxv[x]);
}
}
f[x][0]+=calc(maxv[x]);
} ll fet[MAXN],calsec[MAXN],cal[MAXN]; il void dfs2(rg int x)
{
if(fa[x])
{ // f[fa] shouldn't change
fet[x]=fetch(x);
cal[x]=calc(x);
f[fa[x]][1]-=fet[x];
f[fa[x]][0]-=fet[x];
rg int w=fw[fa[x]];
fw[fa[x]]=fw[x];
f[x][1]+=fetch(fa[x]);
f[x][0]=f[x][1];
if(maxv[fa[x]]==x)
{
f[fa[x]][0]-=cal[x];
f[fa[x]][0]+=calsec[fa[x]];
}
if(calc(fa[x])>calc(secv[x]))
{
secv[x]=fa[x];
if(calc(secv[x])>calc(maxv[x]))
swap(secv[x],maxv[x]);
}
calsec[x]=calc(secv[x]);
f[x][0]+=calc(maxv[x]); f[fa[x]][1]+=fet[x]; // restore
f[fa[x]][0]+=fet[x];
fw[fa[x]]=w;
if(maxv[fa[x]]==x)
{
f[fa[x]][0]-=calsec[fa[x]];
f[fa[x]][0]+=cal[x];
}
}
else
{
fet[x]=fetch(x);
calsec[x]=calc(secv[x]);
cal[x]=calc(x);
} for(rg int i=head[x];i;i=E[i].nx)
{
rg int y=E[i].to;
if(y==fa[x])
continue;
dfs2(y);
}
} int main()
{
freopen("treasure.in","r",stdin);
freopen("treasure.out","w",stdout);
rg int n=read<int>();
for(rg int i=1;i<n;++i)
{
rg int x=read<int>(),y=read<int>(),w=read<int>();
addedge(x,y,w);
addedge(y,x,w);
}
for(rg int i=1;i<=n;++i)
{
read(val[i]);
}
dfs1(1,0);
dfs2(1);
/* for(int i=1;i<=n;++i)
{
printf("%d:\n",i);
printf(" f0=%lld\tf1=%lld\n",f[i][0],f[i][1]);
}*/
for(rg int i=1;i<=n;++i)
{
printf("%lld\n",f[i][0]);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}

标解

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<bitset>
using namespace std;
typedef long long ll;
const int N=610000;
int fi[N],ne[N],len[N],to[N];
ll dp0[N],dp1[N];
ll ans[N],wushi0[N],wushi1[N],val[N];
int pE,n;
//0:考虑回到原点;1:不回到原点
void addE(int u,int v,int l)
{
pE++;to[pE]=v;len[pE]=l;
ne[pE]=fi[u];fi[u]=pE;
}
void dfs(int u,int fa)
{
ll mx=0;
for (int j=fi[u];j;j=ne[j])
{
if (to[j]==fa) continue;
dfs(to[j],u);
if (dp0[to[j]]-2*len[j]>0)
{
dp0[u]+=dp0[to[j]]-2*len[j];
mx=max(mx,len[j]+dp1[to[j]]-dp0[to[j]]);
}
else mx=max(mx,dp1[to[j]]-len[j]);
}
dp0[u]+=val[u];
dp1[u]=dp0[u]+mx;
}
void dfs2(int u,int fa,int le)
{
ans[u]=max(dp0[u]+max(wushi1[u]-le,(ll)0),dp1[u]+max(wushi0[u]-le*2,(ll)0));
ll mx1=0,mx2=0;
for (int j=fi[u];j;j=ne[j])
{
if (to[j]==fa) continue;
ll now;
if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
else now=dp1[to[j]]-len[j];
if (now>mx1) {mx2=mx1;mx1=now;}
else if (now>mx2) mx2=now;
}
ll now;
if (wushi0[u]-2*le>0) now=le+wushi1[u]-wushi0[u];
else now=wushi1[u]-le;
if (now>mx1) {mx2=mx1;mx1=now;}
else if (now>mx2) mx2=now;
for (int j=fi[u];j;j=ne[j])
{
if (to[j]==fa) continue;
wushi0[to[j]]=dp0[u]-max((ll)0,dp0[to[j]]-2*len[j])+max((ll)0,wushi0[u]-2*le);
ll now;
if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
else now=dp1[to[j]]-len[j];
if (now==mx1) wushi1[to[j]]=wushi0[to[j]]+mx2;
else wushi1[to[j]]=wushi0[to[j]]+mx1;
}
for (int j=fi[u];j;j=ne[j])
if (to[j]!=fa) dfs2(to[j],u,len[j]);
}
int main()
{
freopen("treasure.in","r",stdin);
freopen("treasure.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int u,v,l;scanf("%d%d%d",&u,&v,&l);
addE(u,v,l);addE(v,u,l);
}
for (int i=1;i<=n;i++) scanf("%d",&val[i]);
dfs(1,0);
for (int j=fi[1];j;j=ne[j])
if (dp0[to[j]]-2*len[j]>0)
wushi0[to[j]]=dp0[1]-(dp0[to[j]]-2*len[j]);
else wushi0[to[j]]=dp0[1];
ll mx1=0,mx2=0;
for (int j=fi[1];j;j=ne[j])
{
ll now;
if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
else now=dp1[to[j]]-len[j];
if (now>mx1) {mx2=mx1;mx1=now;}
else if (now>mx2) mx2=now;
}
for (int j=fi[1];j;j=ne[j])
{
ll now;
if (dp0[to[j]]-2*len[j]>0) now=len[j]+dp1[to[j]]-dp0[to[j]];
else now=dp1[to[j]]-len[j];
if (now==mx1) wushi1[to[j]]=wushi0[to[j]]+mx2;
else wushi1[to[j]]=wushi0[to[j]]+mx1;
}
ans[1]=dp1[1];
for (int j=fi[1];j;j=ne[j]) dfs2(to[j],1,len[j]);
for (int i=1;i<=n;i++) printf("%lld\n",ans[i]);
return 0;
}

test20181029 宝藏的更多相关文章

  1. 算法:poj1066 宝藏猎人问题。

    package practice; import java.util.Scanner; public class TreasureHunt { public static void main(Stri ...

  2. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  3. zzulioj 1907小火山的宝藏交易(dfs记忆化搜索)

    #include <stdio.h> #include <algorithm> #include <string.h> #include <vector> ...

  4. codevs3196 黄金宝藏

    题目描述 Description 小毛终于到达宝藏点,他意外地发现有一个外星人(名叫Pluto).宝藏是一些太空黄金,有n堆排成一行,每堆中有xi颗黄金.小毛和Pluto决定轮流从中取出黄金,规则是每 ...

  5. bzoj 1924 [Sdoi2010]所驼门王的宝藏(构图,SCC,DP)

    Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...

  6. (zzuli)1907 小火山的宝藏收益

    Description 进去宝藏后, 小火山发现宝藏有N个房间,且这n个房间通过N-1道门联通. 每一个房间都有一个价值为Ai的宝藏, 但是每一个房间也都存在一个机关.如果小火山取走了这个房间的宝藏, ...

  7. zzuli 1907: 小火山的宝藏收益 邻接表+DFS

    Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 113  Solved: 24 SubmitStatusWeb Board Description    ...

  8. [SDOI2010]所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  9. [51nod1474]宝藏图

    有n堆宝藏,每一堆宝藏有一个挖掘所需要的时间ti,有一个价值qi. 现在是做一个宝藏图.这个宝藏图是这样的,宝藏图的形状是一棵二叉树,二叉树刚好有k个叶子结点,从n堆宝藏中选k堆放到二叉树的叶子结点上 ...

随机推荐

  1. 26. Remove Duplicates from Sorted Array(删除排序数组中的重复元素,利用排序的特性,比较大小)

      Given a sorted array, remove the duplicates in-place such that each element appear only once and r ...

  2. Wannafly挑战赛28 Solution

    A:msc和mas Solved. 考虑斐波那契数列,即最多加45次即会超过1e9,直接暴力即可 #include <bits/stdc++.h> using namespace std; ...

  3. CTR预估中的贝叶斯平滑方法(一)原理及实验介绍

    1. 背景介绍 广告形式: 互联网广告可以分为以下三种: 1)展示广告(display ad) 2)搜索广告(sponsored search ad) 3)上下文广告(contextual ad)   ...

  4. 一篇关于Redis的很不错的文章,转载保存下

    绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.这里对 Redis 常见问题做一个总结,解决 ...

  5. HTTP从入门到入土(4)——URI、URL和URN

    URI URI全称:Uniform Resource Identifier,中文名为统一资源标识符.用来标识唯一标识互联网上的信息资源. Web上可用的所有资源,比如html.图像.视频等,都是由UR ...

  6. Thinkphp在Lnmp环境下部署项目先后报错问题解决:_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Home/...Access denied.

    首先报错:_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Home/769e70f2e46f34ceb60619bbda5e4691.php 解决此 ...

  7. 2018-2019-1 20189218《Linux内核原理与分析》第三周作业

    mykernel 实验 实验楼里按步骤运行一切顺利,make等待的时间特别久: 但是,启动mykernel后,实验楼的界面就不响应了,所以还是在自己虚拟机上做这个实验. 虚拟机搭建 mykernel ...

  8. HDU 1712 ACboy needs your help(分组背包入门题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1712 题意: 有个人学习n门课程,a[i][j]表示用j分钟学习第i门课程所能获得的价值,背包容量为一共有m时间 ...

  9. Android -- service 利用广播调用服务的方法

    1. 实现原理,在Service里面注册一个广播接收者, 想要调用的时候app发送出广播, 后台的service里面的广播接收者接收到广播,并调用service里面的方法. 2. 示例代码 MainA ...

  10. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...