题目传送门

题意:

给定一个$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. GitHub : Hello World

    这个写的太好啦,让我也没啥可以写的啦:http://www.open-open.com/lib/view/open1454507333214.html

  2. python之ORM

    pymysql python操作数据库的基本步骤: 导入相应的python模块: 使用connect函数连接数据库,并返回一个connection对象: 通过connection对象的cursor方法 ...

  3. js 选中文字

    选中文字,文字背景是蓝色 当前点击的元素: var e = e || event; var tag = e.target || e.srcElement; 选中文字:window.getSelecti ...

  4. 2017 去哪儿网 研发4.18(offer)

    去哪儿网一面(30分钟) 上来小哥哥先让自我介绍,然后开始问基础,说你计算机专业的,数据结构应该比较扎实吧,先写个快排.然后在我写的时候,小哥哥mac上敲敲打打,应该在看git,我简历上有留git的地 ...

  5. 【Linux学习四】Linux下Vim命令操作

    1.Vim介绍 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性. 第一阶段通过vimtutor的学习,加强vim的熟练度 1.1光标移动 hjkl左 ...

  6. 【51nod 1824】染色游戏

    题目 有 n 个红球, m 个蓝球,从中取出 x 个红球和 y 个蓝球排成一排的得分是 rx⋅by ,其中 r0=b0=1 . 定义 f(t) 表示恰好取出 t 个球排成一排的所有可能局面的得分之和. ...

  7. Python 文件I/O Ⅳ

    Python里的目录: 所有文件都包含在各个不同的目录下,不过Python也能轻松处理.os模块http://www.xuanhe.net/有许多方法能帮你创建,删除和更改目录. mkdir()方法 ...

  8. Spring MVC 面试题

    什么是springMVC?作用? springMVC是一种web层mvc框架,用于替代servlet(处理|响应请求,获取表单参数,表单校验等). 为什么要用springMVC? 基本上,框架的作用就 ...

  9. 【传输管理③】Client集团间的传输(例:开发环境300→310,300→320)

    之前有提到: 每个环境可能有若干个Client(客户端/集团),且每个Client用途都不一样. 如下图所示,开发环境就有300,310和320三个Client. 假设开发人员在Client300中新 ...

  10. react 中的路由 Link 和Route和NavLink

    route是配置,link是使用 https://blog.csdn.net/chern1992/article/details/77186118(copy) 嵌套路由一般使用Route,类似于vue ...