题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743

树形dp+换根。 “从根出发又回到根” 减去 “mx ” 。

注意dfsx里真的要改那些dp[cr],为了下一层的调用。而且还要改回来!为了其他孩子下一层的调用!

注意dfsx里真的要改那些dp[v],为了下一层的调用。而且还要改回来!为了本层的继续调用!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=5e5+;
int n,m,hd[N],xnt,num[N];
ll mx[N],dp[N],ans[N];
bool b[N];
struct Ed{
int nxt,to,w;
Ed(int n=,int t=,int w=):nxt(n),to(t),w(w) {}
}ed[N<<];
void add(int x,int y,int z)
{
ed[++xnt]=Ed(hd[x],y,z);hd[x]=xnt;
ed[++xnt]=Ed(hd[y],x,z);hd[y]=xnt;
}
void updt(int cr,int v,int i)
{
if(num[v])
{
num[cr]+=num[v];
dp[cr]+=dp[v]+(ed[i].w<<);
mx[cr]=max(mx[cr],mx[v]+ed[i].w);
}
}
void dfs(int cr,int f)
{
if(b[cr])num[cr]=;
for(int i=hd[cr],v;i;i=ed[i].nxt)
if((v=ed[i].to)!=f)
{
dfs(v,cr);
updt(cr,v,i);
}
}
void dfsx(int cr,int f)
{
int ynm=num[cr];ll ymx=mx[cr],ydp=dp[cr];
for(int i=hd[cr],v;i;i=ed[i].nxt)
if((v=ed[i].to)!=f)
{
dp[cr]=ydp;mx[cr]=ymx;num[cr]=ynm;
int tnm=num[v];ll tmx=mx[v],tdp=dp[v]; if(num[v])
{
num[cr]-=num[v];
dp[cr]-=dp[v]+(ed[i].w<<);
}
mx[cr]=;
for(int j=hd[cr],u;j;j=ed[j].nxt)
if((u=ed[j].to)!=v&&num[u])mx[cr]=max(mx[cr],mx[u]+ed[j].w); updt(v,cr,i);
ans[v]=dp[v]-mx[v];
dfsx(v,cr);
num[v]=tnm;mx[v]=tmx;dp[v]=tdp;
}
}
int main()
{
scanf("%d%d",&n,&m);int x,y,z;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for(int i=;i<=m;i++)
scanf("%d",&x),b[x]=;
dfs(,);
ans[]=dp[]-mx[];
dfsx(,);
for(int i=;i<=n;i++)printf("%lld\n",ans[i]);
return ;
}

bzoj 3743 [Coci2015]Kamp——树形dp+换根的更多相关文章

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

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

  2. 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686

    换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...

  3. poj3585 Accumulation Degree(树形dp,换根)

    题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...

  4. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  5. [题解](树形dp/换根)小x游世界树

    2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...

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

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

  7. bzoj 1131 [POI2008]Sta 树形dp 转移根模板题

    [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1889  Solved: 729[Submit][Status][Discu ...

  8. Bzoj 1131[POI2008]STA-Station (树形DP)

    Bzoj 1131[POI2008]STA-Station (树形DP) 状态: 设\(f[i]\)为以\(i\)为根的深度之和,然后考虑从他父亲转移. 发现儿子的深度及其自己的深度\(-1\) 其余 ...

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

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

随机推荐

  1. UMP系统架构

  2. JedisCluster API 整理

    windows版redis启动服务器命令:redis-server redis.windows.conf 图表来自菜鸟教程: 列表的操作命令 序号 命令及描述 1 BLPOP key1 [key2 ] ...

  3. 第九章 Odoo 12开发之外部 API - 集成第三方系统

    Odoo 服务器端带有外部 API,可供网页客户端和其它客户端应用使用.本文中我们将学习如何在我们的客户端程序中使用 Odoo 的外部 API.为避免引入大家所不熟悉的编程语言,此处我们将使用基于 P ...

  4. 微信H5支付签名校验错误

    参数一定按照我得顺序写,这样可以不用排序,签名在图二. H5支付最坑的一点就是文档坑爹!!!文档中有一个场景信息字段写的是必填,实际上是不需要的!!因为这个字段找了一下午bug,用签名校验工具是成功的 ...

  5. jquery.cookie.js时间设置

    var expiresDate= new Date(); expiresDate.setTime(expiresDate.getTime() + (120*60*1000)); $.cookie('u ...

  6. python 编程 一次错误记录 -1073740791

    原因是发生在我错把类当做实例化对象使用了

  7. linux命令快速手记 — 让手指跟上思考的速度(四)

    pm2 list:列出pm2方式启动的所有程序 pm2 monit:显示每个应用程序的CPU和内存占用情况 scp:远程复制和本地上传,适用于本地ssh登录到远程服务器 scp root@10.10. ...

  8. java中 &&与& ||与| 的区别

    public class Demo { public static void main(String[] args) { int i = 5; int j = 3; // || 与 | 的区别 boo ...

  9. SpringBoot使用注解方式整合Redis

    1.首先导入使用Maven导入jar包 <dependency> <groupId>org.springframework.boot</groupId> <a ...

  10. vue 实现邮戳边缘

    效果: vue: <template> <div class="couponItem"> <div class="itemLeft" ...