传送门

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

Solution

总体上是用全部的路程减去最大的一条路程

先两次dfs求出每个点全部路程

再两次dfs求出最大一条路径

Code

//By Menteur_Hxy
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
using namespace std;
typedef long long LL; int read() {
int x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
} const int N=500010;
const LL INF=0x7fffffffffffffff;
int n,k,cnt;
int nxt[N<<1],to[N<<1],w[N<<1],head[N],siz[N];
LL dis[N],down[N][2],up[N]; void dfs1(int u,int pre) { //向下
E(i,u) { int v=to[i];
if(v==pre) continue;
dfs1(v,u); siz[u]+=siz[v];
dis[u]+=dis[v]+(siz[v]?w[i]:0);
}
} void dfs2(int u,int pre) { //向上
E(i,u) { int v=to[i];
if(v==pre) continue;
dis[v]=dis[u];
// if(siz[v])dis[v]-=w[i];
// if(siz[v]<k)dis[v]+=w[i];
if(siz[v]==k) dis[v]-=w[i];
else if(!siz[v]) dis[v]+=w[i];
dfs2(v,u);
}
} void dfs3(int u,int pre) { //向下
down[u][0]=down[u][1]=(siz[u]?0:-INF);
E(i,u) { int v=to[i];
if(v==pre) continue;
dfs3(v,u);
if(down[v][0]+w[i]>down[u][0]) down[u][1]=down[u][0],down[u][0]=down[v][0]+w[i];
else if(down[v][0]+w[i]>down[u][1]) down[u][1]=down[v][0]+w[i];
}
} void dfs4(int u,int pre) { //向上
E(i,u) { int v=to[i];
if(v==pre) continue;
if(down[v][0]+w[i]==down[u][0]) up[v]=down[u][1]+w[i];
else up[v]=down[u][0]+w[i];
up[v]=max(up[v],up[u]+w[i]);
dfs4(v,u);
}
} #define add(a,b,c) nxt[++cnt]=head[a],to[cnt]=b,w[cnt]=c,head[a]=cnt
int main() {
n=read(),k=read();
F(i,1,n-1) {
int a=read(),b=read(),c=read();
add(a,b,c),add(b,a,c);
}
F(i,1,k) siz[read()]=1;
dfs1(1,0); dfs2(1,0); dfs3(1,0);
up[1]=(siz[1]?0:-INF); dfs4(1,0);
// F(i,1,n) printf("%lld ",2*dis[i]);cout<<endl;
F(i,1,n) printf("%lld\n",2*dis[i]-max(up[i],down[i][0]));
return 0;
}

[bzoj3743 Coci2015] Kamp(树形dp)的更多相关文章

  1. 【BZOJ3743】[Coci2015]Kamp 树形DP

    [BZOJ3743][Coci2015]Kamp Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举 ...

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

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

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

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

  4. 『kamp 树形dp』

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

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

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

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

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

  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. 【ACM】hdu_zs3_1005_String Matching_201308100920

    String Matching Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)Tota ...

  2. 洛谷 P1535 游荡的奶牛

    P1535 游荡的奶牛 题目描述 Searching for the very best grass, the cows are travelling about the pasture which ...

  3. hdu 1011 树型dp

    #include <cstdio> #include <iostream> #include <cstring> #include <vector> u ...

  4. C++ exit 与 return 浅析

    [摘要] 本文从代码形式.经常使用方式,相关概念,调用关系和比較分析,这5个维度浅析 exit 与 return 在C++的同样点与差别. [常见形式] exit(0):   正常执行程序并退出程序. ...

  5. 一、Redis 基础命令---总括

    1.redis命令不区分大写和小写.可是KEY区分大写和小写. 2.redis-cli -h 127.0.0.1 -p 6379 依据IP/PORT链接服务端 3.redis-server --por ...

  6. CF D. Beautiful numbers (数位dp)

    http://codeforces.com/problemset/problem/55/D Beautiful Numbers : 这个数能整除它的全部位上非零整数.问[l,r]之间的Beautifu ...

  7. jcaptcha进阶

    1.改动CaptchaServiceSingleton类.使用带參构造方法来创建DefaultManageableImageCaptchaService对象. watermark/2/text/aHR ...

  8. Cocos2d-X直接使用OpenGL接口

    Cocos2d-X是基于基于OpenGL ES的2D游戏引擎,所以Cocos2d-X能够直接使用OpenGL接口 首先建立一个Draw类,用于处理OpenGL接口 在Draw.h中加入以下的代码 #i ...

  9. <% %> in html

    $(document).on('click', '.invoiceNumber', function () { var string = <%= StaticHelper.GetCurrentC ...

  10. word2vec (一) 简介与训练过程概要

    摘自:http://blog.csdn.net/thriving_fcl/article/details/51404655 词的向量化与word2vec简介 word2vec最初是Tomas Miko ...