题目传送门

题意:

给定一个$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. nginx第六天

    nginx正向代理 反向代理 Nginx正向代理配置 Nginx正向代理使用场景并不多见. 需求场景1: 如果在机房中,只有一台机器可以联网,其他机器只有内网,内网的机器想用使用yum安装软件包,在能 ...

  2. Java技术综述

    自己打算好好学习下Java,所以想先明晰Java开发中到底有哪些技术,以便以后学习的过程中,可以循序渐进,随着学习的深入,本文将不断更新. Java基础教程将Java的入门基础知识贯穿在一个实例中,逐 ...

  3. Java多线程和并发(八),synchronized底层原理

    目录 1.对象头(Mark Word) 2.对象自带的锁(Monitor) 3.自旋锁和自适应自旋锁 4.偏向锁 5.轻量级锁 6.偏向锁,轻量级锁,重量级锁联系 八.synchronized底层原理 ...

  4. 论文阅读:NETFPGA SUME: TOWARD 100 GBPS AS RESEARCH COMMODITY

    摘要: 数据中心网络的需求增长意味着许多组成技术不在研究社区的预算之内. NETFPGA SUME是基于FPGA的PCI Express板,具有I / O功能,可作为网络接口卡,多端口开关,防火墙或测 ...

  5. python脚本中selenium启动浏览器报错os.path.basename(self.path), self.start_error_message) selenium.common.excep

    在python脚本中,使用selenium启动浏览器报错,原因是未安装浏览器驱动,报错内容如下: # -*- coding:utf-8 -*-from selenium import webdrive ...

  6. JS框架_(JQuery.js)Tooltip弹出式按钮插件

    百度云盘 传送门 密码:7eh5 弹出式按钮效果 <!DOCTYPE html> <html > <head> <meta charset="UTF ...

  7. ES6非常棒的特性-解构

    https://blog.csdn.net/maoxunxing/article/details/79772946

  8. phpfor函数和foreach函数

    PHP for 循环 PHP While 循环 PHP 函数 PHP for 循环执行代码块指定的次数. PHP for 循环 如果您已经提前确定脚本运行的次数,可以使用 for 循环. 语法 for ...

  9. ionic1使用imagepicker在安卓手机上闪退问题

    在上一篇文章中,提到了如何在ionic1中使用imagepicker插件,并且实现该插件显示中文(汉化)问题有兴趣可以看看:ionic1使用ImagePicker插件并且显示中文(汉化) 1.这次要解 ...

  10. SpringBoot启动时的Banner设置

    Spring Boot程序启动的时候输出的由字符组成的Spring符号并不陌生.这个是Spring Boot为自己设计的Banner: 1. 第一种方式:修改的时候,进行设置,在Application ...