【BZOJ3743】[Coci2015]Kamp 树形DP
【BZOJ3743】[Coci2015]Kamp
Description
Input
Output
Sample Input
1 2 4
1 3 1
2 5 1
2 4 2
4 7 3
4 6 2
3
7
Sample Output
15
10
13
16
15
10
HINT
题解:我们先高出这k个点的虚树,先考虑出发点u这个点是虚树上的点,且必须返回出发点时答案是什么。显然答案就是这个虚树的所有边的长度之和*2。
那么如果要返回出发点呢?如果我们再v结束,那么答案就会减去dis(u,v),那么显然dis(u,v)越大越好,所以树形DP求一下每个点到虚树上点的距离最大值即可。
然后如果u不在虚树上呢?那么它还要先走到虚树上,所以再维护一下每个点到虚树上点的距离最小值即可。
代码还是很不可读的~
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=500010;
ll ans;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],head[maxn],p[maxn],q[maxn],s[maxn],fa[maxn],Q[maxn],st[maxn];
ll dep[maxn],f[maxn][2],g[maxn],h[maxn][2],k[maxn];
int n,m,cnt,top,np,mp;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{
p[x]=++p[0],Q[p[0]]=x;
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]) dep[to[i]]=dep[x]+val[i],fa[to[i]]=x,dfs(to[i]);
q[x]=p[0];
}
int main()
{
n=rd(),m=rd();
int i,a,b,c,x,y;
ll d;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
dfs(1);
np=n,mp=0;
memset(f,0xc0,sizeof(f)),memset(g,0xc0,sizeof(g)),memset(h,0x3f,sizeof(h)),memset(k,0x3f,sizeof(k));
for(i=1;i<=m;i++) x=s[i]=rd(),f[x][0]=g[x]=h[x][0]=k[x]=0,np=min(np,p[x]),mp=max(mp,p[x]);
top=1;
for(i=1;i<=n;i++) if(p[i]<=np&&q[i]>=mp&&dep[i]>=dep[top]) top=i;
for(i=n;i>=2;i--)
{
x=Q[i],y=fa[x],d=dep[x]-dep[y];
if(f[y][0]>f[x][0]+d) f[y][1]=max(f[y][1],f[x][0]+d);
else f[y][1]=f[y][0],f[y][0]=f[x][0]+d;
if(!h[x][0]&&x!=top) h[y][0]=0,ans+=(dep[x]-dep[y])<<1;
if(h[y][0]<h[x][0]+d) h[y][1]=min(h[y][1],h[x][0]+d);
else h[y][1]=h[y][0],h[y][0]=h[x][0]+d;
}
for(i=2;i<=n;i++)
{
x=Q[i],y=fa[x],d=dep[x]-dep[y],g[x]=max(g[x],g[y]+d),k[x]=min(k[x],k[y]+d);
if(f[y][0]==f[x][0]+d) g[x]=max(g[x],f[y][1]+d);
else g[x]=max(g[x],f[y][0]+d);
if(h[y][0]==h[x][0]+d) k[x]=min(k[x],h[y][1]+d);
else k[x]=min(k[x],h[y][0]+d);
}
for(i=1;i<=n;i++) printf("%lld\n",ans+2*min(k[i],h[i][0])-max(g[i],f[i][0]));
return 0;
}
【BZOJ3743】[Coci2015]Kamp 树形DP的更多相关文章
- bzoj 3743 [Coci2015]Kamp——树形dp+换根
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...
- bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2
3743: [Coci2015]Kamp Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 484 Solved: 229[Submit][Status ...
- 『kamp 树形dp』
kamp Description jz 市的云台山是个很美丽的景区,小 x 暑期到云台山打工,他的任务是开景区的大巴. 云台山景区有 N 个景点,这 N 个景点由 N-1 条道路连接而成,我们保证这 ...
- bzoj 3743 [ Coci 2015 ] Kamp —— 树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 一开始想到了树形DP,处理一下子树中的最小值,向上的最小值,以及子树中的最长路和向上的 ...
- 2018.09.28 bzoj3743: [Coci2015]Kamp(树形dp)
传送门 这是一道很有意思的题. 我们把所有的关键点都提出来,当成一棵有边权的虚树. 然后发现虚树上除最后不回到虚根的那条路径外外每条边都会被走两遍. 显然要让答案最优,不走的路径应该在虚树的直径上,于 ...
- [bzoj3743 Coci2015] Kamp(树形dp)
传送门 Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举行聚会. 聚会结束后需要一辆车从举行聚会的 ...
- [Bzoj3743][Coci2015] Kamp【换根Dp】
Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...
- BZOJ3743 COCI2015Kamp(树形dp)
设f[i]为由i开始遍历完子树内所要求的点的最短时间,g[i]为由i开始遍历完子树内所要求的点最后回到i的最短时间.则g[i]=Σ(g[j]+2),f[i]=min{g[i]-g[j]+f[j]-1} ...
- bzoj3743: [Coci2015]Kamp
首先树dp求出一个点的答案 然后再一遍dfs换根(是叫做换根吗.. 详见代码 #include <iostream> #include <cstdio> #include &l ...
随机推荐
- C#中out与ref区别
一.ref(参考)与out区别 1.out(只出不进) 将方法中的参数传递出去,在方法中将该参数传递出去之前需要在该方法起始赋初值:在方法外传递的该参数可以不用赋值: 简单理解就是:将一个东西抛出去之 ...
- 用word2vec对语料进行训练
在Linux上安装好word2vec, 进入trunk文件夹,把分词后的语料文件放在trunk文件夹内,执行:./word2vec -train tt.txt -output vectors.bin ...
- [React] Override webpack config for create-react-app without ejection
The default service worker that comes with create-react-app doesn't allow for very much configuratio ...
- ListView:聊天界面
一.最终成型图 二.主界面xml布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- 标准库Allocator的简易实现(二)
自己实现Allocator并不难,其实只需要改变allocate和deallocate,来实现自己的内存分配策略. 下面是一个std::allocator的模拟实现 #ifndef ALLOCAT ...
- HTTP Analyzer过滤器使用
HTTP Analyzer简单易用,真实抓包居家必备啊,上一次分享了Fiddler的过滤条件,这次介绍下这款软件的过滤,首先按照肯定是按照软件类型分类喽: 1.按照软件过滤: 这样只会显示chrome ...
- HTTP常用的请求头和响应头
1.请求头 Connection:表示是否需要持久连接.若值为Keep-Alive,就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间.要实现这一点, ...
- rk3288 LED上加入heartbeat功能
平台:瑞芯的rk3288 作者:fulinux *****本文同意转载.只是请注明出处:http://blog.csdn.net/fulinus**** 1.硬件环境 随意选取一个GPIO引脚作为he ...
- EFFECTIVE JAVA 类和接口
第十六条:复合优先于继承 //这是一个不好的类---执行的结果 addCount = 4(addAll的实现依赖于HashSet的add方法,InstrumentHashSet方法重写了add方法有执 ...
- Git学习小结
版本控制工具 集中式: CVS SVN 集大成者 分布式:git 创始人:inux Towards 2005年 工具 最好使用linux(oh-my-zsh) gitbash -> cygwin ...