题目传送门

题意:

给定一个$N$个点的树,第$i$条边的长度是$A_i$,求每个点到其他所有点的最长距离。
数据范围:
$n ≤ 10000$,$A_i ≤ 10_9$

分析

首先,从随便哪个节点($1$号节点(工具人))开始进行$dfs$,处理出所有点到$1$的距离$dis[i]$

然后,考虑$i$号节点的最远点。

有两种情况:

一种是最远点在$i$的子树内,直接求就完事了(之前我们在以$1$为根的时候已经干过这件事情了)

另外一种就是经过了$i$和他父亲的那一条边,最远点在父亲的其它儿子中(或者是父亲的父亲的儿子中,当然,在把父亲看成根的情况下,就是父亲的其它儿子中,并且根据换根的做法,之前根已经被换到了父亲,答案是现成的)

设离$i$最远的距离为$dist$,它父亲的子树中(以$1$为根节点形成的数)离它父亲最远的距离为$d1$,不在它父亲的子树中(通过了父亲<->爷爷这条边的)离它父亲最远的距离为$d2$,$i$和它父亲的的那一条边的权值为$w$

这种情况下,$dis=max(d1,d2)+w$

对于点$i$的答案,两种情况取$min$就可以啦。

但是这样还存在一个问题,就是如果父亲的子树中离父亲最远的那条路经过了$i$,那么$dis$就不能从$d1$推过来,因为如果$max(d1,d2)=d1$,那就是$dis=d1+w$,而这肯定是不成立的,$d1$就包含了$w$和$i$到$i$子树中最远的路。

那么还需要维护一个次长路,当$i$在父亲到父亲子树中最远点的路径上时,要用次长路更新(这种情况下,这个次长路就是父亲的除$i$之外的最大儿子。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define N 10005
#define INF 0x3f3f3f3f
#define ll long long
int rd()
{
int f=,x=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+(c^);c=getchar();}
return f*x;
}
int n;
int d1[N]/*距离i最长长度*/,d2[N]/*距离i次长长度*/;
//d1[] d2[]都是子树i以内的
int son[N]/*最长长度对应儿子编号*/;
int anc[N]/*父亲方向最长长度(子树以外最长长度)*/;
int ans[N];//答案
struct node{
int v,w;
};
vector<node>G[N];
void dfs(int u,int f)
{
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].v,w=G[u][i].w;
if(v==f) continue;
dfs(v,u);
if(d1[u]<d1[v]+w)
{//从这个儿子能得到目前最长的长度
d2[u]=d1[u];
son[u]=v;
d1[u]=d1[v]+w;
}/*要写else 大儿子和二儿子要不一样*/
else if(d2[u]<d1[v]+w)
d2[u]=d1[v]+w;
/*
d2[v]不会被纳入答案中
大儿子和二儿子要不一样
无论如何都不会轮到d2[v]来做贡献
如果d1[v]可以贡献 就贡献了 d2[v]也不会被用到
如果d1[v]不能贡献 d2[v]就更不会被用到了
*/
}
ans[u]=d1[u];
}
void dfs2(int u,int f)
{
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].v,w=G[u][i].w;
if(v==f) continue;
if(v!=son[u])
anc[v]=max(anc[u]+w,d1[u]+w);
else anc[v]=max(anc[u]+w,d2[u]+w);
ans[v]=max(ans[v],anc[v]);
dfs2(v,u);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<=n;i++)
{
int v=rd(),w=rd();
node t;t.v=v,t.w=w;
G[i].push_back(t);
t.v=i;
G[v].push_back(t);
d1[i]=d2[i]=son[i]=anc[i]=ans[i]=;
}
d1[]=d2[]=son[]=anc[]=ans[]=;
dfs(,);
dfs2(,);
for(int i=;i<=n;i++)
{
printf("%d\n",ans[i]);
G[i].clear();
}
}
return ;
}

Code

HDU2196 Computer【换根dp】的更多相关文章

  1. [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]

    题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...

  2. 2018.10.15 NOIP训练 水流成河(换根dp)

    传送门 换根dp入门题. 貌似李煜东的书上讲过? 不记得了. 先推出以1为根时的答案. 然后考虑向儿子转移. 我们记f[p]f[p]f[p]表示原树中以ppp为根的子树的答案. g[p]g[p]g[p ...

  3. 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市

    P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...

  4. 小奇的仓库:换根dp

    一道很好的换根dp题.考场上现场yy十分愉快 给定树,求每个点的到其它所有点的距离异或上m之后的值,n=100000,m<=16 只能线性复杂度求解,m又小得奇怪.或者带一个log像kx一样打一 ...

  5. 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4827 ​ 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...

  6. Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)

    题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...

  7. bzoj 3566: [SHOI2014]概率充电器 数学期望+换根dp

    题意:给定一颗树,树上每个点通电概率为 $q[i]$%,每条边通电的概率为 $p[i]$%,求期望充入电的点的个数. 期望在任何时候都具有线性性,所以可以分别求每个点通电的概率(这种情况下期望=概率 ...

  8. codeforces1156D 0-1-Tree 换根dp

    题目传送门 题意: 给定一棵n个点的边权为0或1的树,一条合法的路径(x,y)(x≠y)满足,从x走到y,一旦经过边权为1的边,就不能再经过边权为0的边,求有多少边满足条件? 思路: 首先,这道题也可 ...

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

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

  10. 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$

    正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...

随机推荐

  1. shell知识点(一)

    Shell1.概述Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核还是一个功能相当强大的编程语言,易编写.易调试.灵活性强2.shell解析器查看linux提供的shell ...

  2. http协议和i/o模型

    http协议----基于请求报文和响应报文完成一次http事务 应用层协议格式有两种: 文本(开发容易,但交互解析困难如http smtp),二进制(交互解析容易,但理解起来困难memocache) ...

  3. Mybaist 注解 foreach 嵌套循环实现批量插入

    第一种写法(#使用占位符推荐): @Insert("<script>" + " insert into ${tb} " +" <fo ...

  4. Qt修改图片的背景色及设置背景色为透明的方法

    先上干货. Qt下修改图片背景色的方法: 方法一: QPixmap CKnitWidget::ChangeImageColor(QPixmap sourcePixmap, QColor origCol ...

  5. 什么是弹性盒子 ( Flex Box)?

    ㈠什么是弹性盒子? 弹性盒子是 CSS3 的一种新的布局模式.引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列.对齐和分配空白空间. 弹性盒子由弹性容器(Flex con ...

  6. Arthas--Java在线分析诊断工具(阿尔萨斯)

    序言 Arthas是一款阿里巴巴开源的 Java 线上诊断工具,功能非常强大,可以解决很多线上不方便解决的问题. 资料 https://blog.csdn.net/youanyyou/article/ ...

  7. HTML jQuery 文档操作 - html() 方法

    jQuery 文档操作 - html() 方法 jQuery 文档操作参考手册 实例 设置所有 p 元素的内容: $(".btn1").click(function(){ $(&q ...

  8. 微信小程序需求IIS服务器配置https关于SSL,TLS的综合解决方案

    SpringBoot配置SSL同时支持http和https访问 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Socke ...

  9. crossdomain.xml解决跨域问题

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  10. 2019年6月Github最新开源java项目

    目录 1.halo,这是一个轻快,简洁,功能强大,使用Java开发的博客系统. 2.jeecg-boot 3.CS-Notes 4.JavaGuide 5.advanced-java 6.mall-l ...