HDU2196 Computer【换根dp】
题意:
给定一个$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】的更多相关文章
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
- 2018.10.15 NOIP训练 水流成河(换根dp)
传送门 换根dp入门题. 貌似李煜东的书上讲过? 不记得了. 先推出以1为根时的答案. 然后考虑向儿子转移. 我们记f[p]f[p]f[p]表示原树中以ppp为根的子树的答案. g[p]g[p]g[p ...
- 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市
P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...
- 小奇的仓库:换根dp
一道很好的换根dp题.考场上现场yy十分愉快 给定树,求每个点的到其它所有点的距离异或上m之后的值,n=100000,m<=16 只能线性复杂度求解,m又小得奇怪.或者带一个log像kx一样打一 ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...
- Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)
题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...
- bzoj 3566: [SHOI2014]概率充电器 数学期望+换根dp
题意:给定一颗树,树上每个点通电概率为 $q[i]$%,每条边通电的概率为 $p[i]$%,求期望充入电的点的个数. 期望在任何时候都具有线性性,所以可以分别求每个点通电的概率(这种情况下期望=概率 ...
- codeforces1156D 0-1-Tree 换根dp
题目传送门 题意: 给定一棵n个点的边权为0或1的树,一条合法的路径(x,y)(x≠y)满足,从x走到y,一旦经过边权为1的边,就不能再经过边权为0的边,求有多少边满足条件? 思路: 首先,这道题也可 ...
- [Bzoj3743][Coci2015] Kamp【换根Dp】
Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...
- 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$
正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...
随机推荐
- 高大上的微信小程序中渲染html内容—技术分享
大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...
- DevExpress ASP.NET v19.1版本亮点:发布全新的Gantt控件
行业领先的.NET界面控件DevExpress 发布了v19.1版本,本文将以系列文章的方式为大家介绍DevExpress ASP.NET Controls v19.1中新增的一些控件及增强的控件功能 ...
- python广度遍历文件夹
import os from collections import deque path = r"E:\Python" queue = deque([])#队列 queue.app ...
- document.writeln绑定数据 --点击跳转添加样式
document.writeln(" "); document.writeln(" "); document.writeln(" "); d ...
- 洛谷P3294 [SCOI2016]背单词——题解
题目传送 阅读理解题题意解释可以看这位大佬的博客. 发现求后缀与倒序求前缀是等价的,而找前缀自然就想到了trie树.将所有字符串翻转后再建入trie树中,再对每一个字符串翻转后从trie树中找前缀,就 ...
- jQuery_attr()操作
下面来介绍jQuery的属性attr()操作: <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...
- Spring boot之添加JSP支持
大纲 (1) 创建Maven web project: (2) 在pom.xml文件添加依赖 (3) 配置application.properties支持jsp (4) 编写测试Controller ...
- Java 里volatile关键字是什么意思啊?如何使用呢?
一旦一个并发共享变量(类的成员变量.静态成员变量)被 volatile 关键字修饰就具备了可见性(即一个线程修改了一个变量的值对于另一个线程来说是立即可见的)和有序性(即禁止进行指令重排序),实质是在 ...
- 20175212童皓桢 《Java程序设计》第11周学习总结
20175212童皓桢 <Java程序设计>第11周学习总结 教材学习内容总结 一.URL类 1.一个URL对象通常包含最基本的三部分信息:协议.地址.资源 2.构造方法: public ...
- vue项目内嵌入到app input type=file 坑(文件上传插件)
w问题描述: 我用vue-cli完成的一个移动端项目,内嵌到app当中,用原生的input type=file 来完成文件上传.在安卓下没有问题但是在苹果手机 上传第二次手机就会发生白屏 并无缘无故跳 ...