【BZOJ3743】[Coci2015]Kamp

Description

一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的。
有K个人(分布在K个不同的点)要集中到一个点举行聚会。
聚会结束后需要一辆车从举行聚会的这点出发,把这K个人分别送回去。
请你回答,对于i=1~n,如果在第i个点举行聚会,司机最少需要多少时间把K个人都送回家。

Input

第一行两个数,n,K。
接下来n-1行,每行三个数,x,y,z表示x到y之间有一条需要花费z时间的边。
接下来K行,每行一个数,表示K个人的分布。

Output

输出n个数,第i行的数表示:如果在第i个点举行聚会,司机需要的最少时间。

Sample Input

7 2
1 2 4
1 3 1
2 5 1
2 4 2
4 7 3
4 6 2
3
7

Sample Output

11
15
10
13
16
15
10

HINT

【数据规模】
K <= N <= 500000
1 <= x,y <= N, 1 <= z <= 1000000

题解:我们先高出这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的更多相关文章

  1. bzoj 3743 [Coci2015]Kamp——树形dp+换根

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...

  2. bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2

    3743: [Coci2015]Kamp Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 229[Submit][Status ...

  3. 『kamp 树形dp』

    kamp Description jz 市的云台山是个很美丽的景区,小 x 暑期到云台山打工,他的任务是开景区的大巴. 云台山景区有 N 个景点,这 N 个景点由 N-1 条道路连接而成,我们保证这 ...

  4. bzoj 3743 [ Coci 2015 ] Kamp —— 树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 一开始想到了树形DP,处理一下子树中的最小值,向上的最小值,以及子树中的最长路和向上的 ...

  5. 2018.09.28 bzoj3743: [Coci2015]Kamp(树形dp)

    传送门 这是一道很有意思的题. 我们把所有的关键点都提出来,当成一棵有边权的虚树. 然后发现虚树上除最后不回到虚根的那条路径外外每条边都会被走两遍. 显然要让答案最优,不走的路径应该在虚树的直径上,于 ...

  6. [bzoj3743 Coci2015] Kamp(树形dp)

    传送门 Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举行聚会. 聚会结束后需要一辆车从举行聚会的 ...

  7. [Bzoj3743][Coci2015] Kamp【换根Dp】

    Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...

  8. 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} ...

  9. bzoj3743: [Coci2015]Kamp

    首先树dp求出一个点的答案 然后再一遍dfs换根(是叫做换根吗.. 详见代码 #include <iostream> #include <cstdio> #include &l ...

随机推荐

  1. remeber me即记住我功能

    1.登录过程中的记住我功能如图: 2.这样在登录认证的时候,客户端会传递两个cookie:remember_token和Tsession 3.即使客户端不传递cookie中的Tsession,只传递r ...

  2. Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details.

    在android上发布遇到 androidSDK无法找到的问题 http://www.jianshu.com/p/fe4c334ee9fe

  3. Unity Dotween build error

    unity这东西感觉挺坑 在mac上build的时候遇到error IL2CPP error for method 'System.Void DG.Tweening.DOTweenPath::DORe ...

  4. spring boot 引用外部配置文件

    java -jar xx.jar -Dspring.config.location=/data/apps/xx/application-prod.properties

  5. ElasticSearch高级查询

    ElasticSearch高级查询 https://www.imooc.com/video/15759/0 ElasticSearch查询 1,子条件查询:特定字段查询所指特定值 1.1query c ...

  6. zoj 3888 Twelves Monkeys 二分+线段树维护次小值

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemCode=3888 Twelves Monkeys Time Limit: 5 ...

  7. PS 文字有锯齿怎么办

    1 可以在矢量绘图软件里面做,就没有锯齿了,画好之后导入到PS即可. 2 可以把PSD文件的像素值变大一些,比如调成500像素/英寸,但是这样会导致做出来的东西体积比较大,所以最好还是学会矢量绘图.

  8. S4:装饰模式 Decorator

    动态的给一个对象添加额外的一些职责,就增加功能而言,比继承更具灵活性. 如果仅有一个ConcreateComponent,也可以让Decorator继承ConcreateComponent来实现装饰功 ...

  9. ListView:聊天界面

    一.最终成型图 二.主界面xml布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  10. eclipse显示包的层次关系

    如何在eclipse中显示包的层次关系呢?如下图所示