首先树dp求出一个点的答案

然后再一遍dfs换根(是叫做换根吗..

详见代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define ll long long
#define N 500005
#define M 1000006 using namespace std;
inline int read(){
int ret=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
} struct edge{
int adj,next,len;
edge(){}
edge(int _adj,int _next,int _len):adj(_adj),next(_next),len(_len){}
} e[M];
int n,g[N],m;
void AddEdge(int w,int u,int v){
e[++m]=edge(v,g[u],w);g[u]=m;
e[++m]=edge(u,g[v],w);g[v]=m;
} ll f[N],h[N],t[N],t0[N];
ll f0[N],h0[N];
int size[N],l[N];
int size0[N];
bool vis[N];
void dfs(int u){
vis[u]=1;
f[u]=l[u];h[u]=2*l[u];t[u]=0;t0[u]=0;
for (int i=g[u];i;i=e[i].next){
int v=e[i].adj;
if (vis[v]) continue;
l[v]=e[i].len;
dfs(v);
f[u]+=h[v];
h[u]+=h[v];
t0[u]=max(t0[u],h[v]-f[v]);
if (t0[u]>t[u]) swap(t0[u],t[u]);
size[u]+=size[v];
}
if (!size[u]) f[u]=h[u]=0;
else f[u]-=t[u];
vis[u]=0;
} ll ans[N];
void solve(int u){
vis[u]=1; f[u]=l[u];h[u]=2*l[u];t[u]=0;t0[u]=0;
for (int i=g[u];i;i=e[i].next){
int v=e[i].adj;
l[v]=e[i].len;
f[u]+=h[v];
h[u]+=h[v];
t0[u]=max(t0[u],h[v]-f[v]);
if (t0[u]>t[u]) swap(t0[u],t[u]);
size[u]+=size[v];
}
if (!size[u]) f[u]=h[u]=0;
else f[u]-=t[u]; ans[u]=f[u];
f0[u]=f[u];h0[u]=h[u];
size0[u]=size[u];
for (int i=g[u];i;i=e[i].next){
int v=e[i].adj;
if (vis[v]) continue;
swap(l[u],l[v]);
if ((size[u]-=size[v])){
h[u]+=(ll)2*l[u]-h[v];
f[u]+=(ll)l[u]-h[v];
if (h[v]-f[v]==t[u]) f[u]+=t[u]-t0[u];
}
else f[u]=h[u]=0; solve(v); f[u]=f0[u];h[u]=h0[u];
size[u]=size0[u];
swap(l[u],l[v]);
}
vis[u]=0;
} int main(){
n=read();int men=read();
for (int i=1;i<n;++i) AddEdge(read(),read(),read());
memset(size,0,sizeof(size));
while (men--) ++size[read()];
memset(vis,0,sizeof(vis));
l[1]=0;
dfs(1);
solve(1);
for (int i=1;i<=n;++i) printf("%lld\n",ans[i]);
return 0;
}

  

bzoj3743: [Coci2015]Kamp的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [Coci2015]Kamp

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

  7. BZOJ3743 : [Coci2014]Kamp

    d[x][0]表示x点向下走且回到x点的最少代价 d[x][1]表示x点向下走但不回到x点的最少代价 d[x][2]表示x点向下走的最长路 d[x][3]表示x点向下走的次长路 u[x][0]表示x点 ...

  8. bzoj 3743: [Coci2015]Kamp【树形dp】

    两遍dfs一遍向下,一边向上,分别记录子树内人数a,当前点到所有点的距离b,最大值c和次大值d,最大值子树p 然后答案是2b-c #include<iostream> #include&l ...

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

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

随机推荐

  1. poj3281 Dining

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14316   Accepted: 6491 Descripti ...

  2. JS读取写入删除COOKIE的各种操作

    1. .NET后置代码中获取 Response.Redirect("http://www.baidu.com?id=" +Request.Cookies["size&qu ...

  3. php 中的curl

    ① curl上传文件 <?php $postData=array( 'name'=>'123', 'upload'=>'@E:/wamp/www/function/result.zi ...

  4. Apache配置中的ProxyPass 和 ProxyPassReverse

    apache中的mod_proxy模块用于url的转发,即具有代理的功能.应用此功能,可以很方便的实现同tomcat等应用服务器的整合,甚者可以很方便的实现web集群的功能. 例如使用apache作为 ...

  5. http://www.cnblogs.com/figure9/p/developer-reading-list.html

    http://www.cnblogs.com/figure9/p/developer-reading-list.html

  6. FineUI v3.3.2发布!目前最稳定版本,五年陈酿!

    关于FineUI基于 ExtJS 的专业 ASP.NET 控件库. FineUI的使命创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No We ...

  7. Word Excel 操作总结

    1.与office无关使用 Aspose.Cells.dll,Aspose.Words.dll 2.使用Microsoft.Office.Interop.Excel Microsoft.Office. ...

  8. 深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件

    [整理]   在求解最优化问题中,拉格朗日乘子法(Lagrange Multiplier)和KKT(Karush Kuhn Tucker)条件是两种最常用的方法.在有等式约束时使用拉格朗日乘子法,在有 ...

  9. js中递归函数的使用介绍

    所谓的递归函数就是在函数体内调用本函数.使用递归函数一定要注意,处理不当就会进入死循环.递归函数只有在特定的情况下使用 ,比如阶乘问题 递归函数是在一个函数通过名字调用自身的情况下构成的,如下所示: ...

  10. python基础-基本数据类型总结_整型(int)_字符型(str)_day3

     一.基本数据类型 1.整型(int) ps1:数字 int ,所有的功能,都放在int里a1 = 123a1 = 456 ps2: int 将字符串转换为数字 # -int # 将字符串转换为数字 ...