这道题用到了4个dfs,分别是找出所有家的最小生成树,找出一点距离树的最小距离,找出每个点儿子距离的最大值(不包括父亲,也就是指不包括根节点的子树),用父亲的值来更新自己

因为我们可以知道:如果我们在树上,那么最短的距离就是树的长度的两倍-距自己最远的点的距离,当我们不在树上时,就得先走到树上(这条路径是唯一的),然后再重复刚才的过程

找出生成树比较简单,重点是找出距树上一点最远的点的距离,这里先找出除了父亲之外每个子树的距离,求出最大和第二,然后再用父亲更新自己的距离,很难想到

#include<iostream>
#include<stdio.h>
#include<string.h>
#define N 1000010
using namespace std;
typedef long long ll;
ll tot;
int cnt=-;
int head[N],to[N],next[N],w[N],used[N],nearest_node[N];
ll dis[N],max_dis[N],sec_dis[N],min_dis[N];
int max_dis_node[N],sec_dis_node[N];
bool k[N],on_tree[N]; void insert(int u,int v,int c)
{
next[++cnt]=head[u];
head[u]=cnt;
to[cnt]=v;
w[cnt]=c;
} ll max(ll x,ll y)
{
return x>y?x:y;
} ll min(ll x,ll y)
{
return x<y?x:y;
} void init()
{
memset(head,-,sizeof(head));
memset(to,-,sizeof(to));
memset(next,-,sizeof(next));
memset(used,,sizeof(used));
memset(on_tree,false,sizeof(on_tree));
memset(min_dis,,sizeof(min_dis));
memset(nearest_node,,sizeof(nearest_node));
memset(dis,,sizeof(dis));
memset(max_dis,,sizeof(max_dis));
} bool dfs1(int u)//找树
{
used[u]=;
for(int i=head[u];~i;i=next[i])
{
int v=to[i];
if(!used[v])
{
bool f2=dfs1(v);
if(f2)
{
on_tree[u]|=f2;
tot+=w[i];
}
dfs1(v);
}
}
return on_tree[u];
} void dfs2(int u)//找树距
{
used[u]=; if(on_tree[u]) nearest_node[u]=u;
for(int i=head[u];~i;i=next[i])
{
int v=to[i];
if(!on_tree[v]&&!used[v])
{
min_dis[v]=min_dis[u]+w[i];
nearest_node[v]=nearest_node[u];
}
if(!used[v]) dfs2(v);
}
} ll dfs3(int u)//儿子的最大距离
{
used[u]=;
for(int i=head[u];~i;i=next[i])
{
int v=to[i];
if(!used[v]&&on_tree[v])
{
ll dis=dfs3(v)+w[i];
if(dis>max_dis[u])
{
sec_dis[u]=max_dis[u];
max_dis[u]=dis;
max_dis_node[u]=v;
}
else if(dis>sec_dis[u])
{
sec_dis[u]=dis;
}
}
}
return max_dis[u];
} void dfs4(int u,ll last_max)
{
used[u]=;
for(int i=head[u];~i;i=next[i])
{
int v=to[i];
ll temp=max(last_max,max_dis[u]);
dis[u]=max(last_max,max_dis[u]);
if(!used[v]&&on_tree[v])
{
if(max_dis_node[u]==v)
{
dfs4(v,max(last_max,sec_dis[u])+w[i]);
}
else dfs4(v,max(last_max,max_dis[u])+w[i]);
}
}
} int main()
{
init();
int n,k; scanf("%d%d",&n,&k);
for(int i=;i<n;i++)
{
int u,v,c; scanf("%d%d%d",&u,&v,&c);
insert(u,v,c); insert(v,u,c);
}
int x;
for(int i=;i<=k;i++)
{
scanf("%d",&x); on_tree[x]=true;
}
dfs1(x); memset(used,,sizeof(used));
dfs2(x); memset(used,,sizeof(used));
dfs3(x); memset(used,,sizeof(used));
dfs4(x,);
/* printf("tot=%d\n",tot);
printf("-------------\n");
for(int i=1;i<=n;i++)
printf("%d ",dis[i]);
printf("\n------------\n"); */
for(int i=;i<=n;i++)
printf("%lld\n",*tot+min_dis[i]-dis[nearest_node[i]]);
return ;
}

bzoj 3743的更多相关文章

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

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

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

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

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

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

  4. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  5. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  6. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  7. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  8. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  9. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

随机推荐

  1. Unity 5 WebGL vs Web Player

    起原 Unity5.3中看到Web Player未来将到被取消,根据Unity官方blog中称Unity5.4中将会移除web player. 本文从我知道的知识比较一下webPlayer和WebGL ...

  2. SecurityError Error 2148 SWF 不能访问本地资源

    错误提示: SWF 文件不能被本地访问 不能访问本地 只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源 错误信息: SecurityError: Error #2148: ...

  3. 万能的 SQL编程

    简介:T-SQL语句创建库.创建表和听.和添加约束等.T-SQL是数据库结构化查询语言,常见的增加.删出.修改.查询.创建库和创建表的语句,还支持定义变量.输出语句.逻辑控制语句(IF.CASE.WH ...

  4. addClass, removeClass, toggleClass(从jquery中抠出来)

    <div id="d3" class="cur"></div> var mylibs = (function(){ var rtrim ...

  5. BZOJ 2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 3312  Solved: 1971[Submit][Statu ...

  6. php常见问题

    1,新安装的lamp在打开php文件的时候出现access forbid问题,这个出现的原因是directory的路径权限问题,解决方法 将httpd.conf中的 <Directory /&g ...

  7. NET Core HTTP 管道

    ASP.NET Core HTTP 管道中的那些事儿   前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Cor ...

  8. 协程python

    python中协程 在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping ...

  9. 一个C++宏定义与枚举定义重复的编译错误

    C++的开发效率低是众所周知的,原因比如有: 语言复杂度高 编译效率低 工具链不够完整高效(尤其是linux下) 另外一个恐怕是不少编译错误让人摸不着头脑,今天碰到一个,举个例子: #include ...

  10. Theano3.4-练习之多层感知机

    来自http://deeplearning.net/tutorial/mlp.html#mlp Multilayer Perceptron note:这部分假设读者已经通读之前的一个练习 Classi ...