这道题用到了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. createDocumentFragment() 创建文档碎片节点

    var aqiData = [ ["北京", 90], ["上海", 50], ["福州", 10], ["广州", 5 ...

  2. Jmeter常见问题

    收集工作中JMeter遇到的各种问题   1.  JMeter的工作原理是什么? 向服务器提交请求:从服务器取回请求返回的结果.   2.  JMeter的作用? JMeter可以用于测试静态或者动态 ...

  3. Flex布局教程及属性速查

    一.Flex布局介绍 伸缩盒模型(flexbox)是一个新的盒子模型,意为"弹性布局",用来为盒状模型提供最大的灵活性,主要优化了UI布局.Flexbox的功能主要包手:简单使用一 ...

  4. [记录]ASP.NET MVC 2.0 如何使用Html.RadioButtonFor?

    在MVC 2.0里支持强类型实体绑定,可以直接使用如 <%: Html.TextBoxFor(model => model.Description, new { @class=" ...

  5. window.open与window.close的兼容性问题

    window.open(页面地址url,打开的方式) 方法 打开一个新的窗口(页面) 如果url为空,则默认打开一个空白页面 如果打开方式为空,默认为新窗口方式打开 返回值:返回新打开窗口的windo ...

  6. angular的uiRouter服务学习(5) --- $state.includes()方法

    $state.includes方法用于判断当前激活状态是否是指定的状态或者是指定状态的子状态. $state.includes(stateOrName,params,options) $state.i ...

  7. .NET Framework 中的所有类型

    .NET Framework 中的所有类型不是值类型就是引用类型. 值类型是使用对象实际值来表示对象的数据类型. 如果向一个变量分配值类型的实例,则该变量将被赋以该值的全新副本. 引用类型是使用对对象 ...

  8. usb驱动开发17之设备生命线

    拜会完了山头的几位大哥,还记得我们从哪里来要到哪里去吗?时刻不能忘记自身的使命啊.我们是从usb_submit_urb()最后的那个遗留问题usb_hcd_submit_urb()函数一路走来,现在就 ...

  9. SQL2012删除作业失败的处理

    修改msdb数据库中的过程sp_delete_job,如下: USE [msdb] GO /****** Object: StoredProcedure [dbo].[sp_delete_job] S ...

  10. Visual Studio 2012 cannot identify IHttpActionResult

    使用ASP.NET Web API构造基于restful风格web services,IHttpActionResult是一个很好的http结果返回接口. 然而发现在vs2012开发环境中,Syste ...