求树上任意一点所能到达的最远距离 - 树上dp
Hint: the example input is corresponding to this graph. And from
the graph, you can see that the computer 4 is farthest one from 1, so S1
= 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer
5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
file contains multiple test cases.In each case there
is natural number N (N<=10000) in the first line, followed by (N-1)
lines with descriptions of computers. i-th line contains two natural
numbers - number of computer, to which i-th computer is connected and
length of cable used for connection. Total length of cable does not
exceed 10^9. Numbers in lines of input are separated by a
space.OutputFor each case output N lines. i-th line must contain number
Si for i-th computer (1<=i<=N).Sample Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4
题意 : 给你一颗树,以及树上两点之间的距离,求任意一点所能到的最远的距离。
思路分析:
对于这个问题,我们可以这样去思考,对于一颗树可以很方便的求出 以当前节点为根节点其所能到达的最远距离,但是这样并不能得到所有的节点的答案,其他的节点需要以其再考虑一下当前节点向上走的情况

再考虑 2 这个节点的时候其最优值可能来自 2 这个子树,也可能来自于右侧的这颗红色的树,即向上走
dp[x][0] 表示 x 节点向下走的最大值, dp[x][1]表示 x 节点向下走的次大值, dp[x][2] 表示 x 节点向上走的最大值。
代码示例:
const int maxn = 1e4+5; int n;
struct node
{
int to, cost; node(int _to=0, int _cost=0):to(_to), cost(_cost){}
};
vector<node>ve[maxn];
int dp[maxn][3];
int p[maxn]; void dfs1(int x, int fa){ for(int i = 0; i < ve[x].size(); i++){
int to = ve[x][i].to;
int cost = ve[x][i].cost;
if (to == fa) continue; dfs1(to, x);
if (dp[x][0] <= dp[to][0]+cost){
dp[x][1] = dp[x][0];
dp[x][0] = dp[to][0]+cost;
p[x] = to;
}
else if (dp[x][1] < dp[to][0]+cost){
dp[x][1] = dp[to][0]+cost;
}
}
}
void dfs2(int x, int fa){ for(int i = 0; i < ve[x].size(); i++){
int to = ve[x][i].to;
int cost = ve[x][i].cost;
if (to == fa) continue; if (to != p[x]){
dp[to][2] = max(dp[x][0]+cost, dp[x][2]+cost);
}
else dp[to][2] = max(dp[x][1]+cost, dp[x][2]+cost);
dfs2(to, x); //printf("++++ %d %d %d \n", x, to, dp[to][2]);
}
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int x, y;
while(~scanf("%d", &n)){
for(int i = 1; i <= n; i++) ve[i].clear();
for(int i = 2; i <= n; i++){
scanf("%d%d", &x, &y);
ve[i].push_back(node(x, y));
ve[x].push_back(node(i, y));
}
memset(dp, 0, sizeof(dp));
dfs1(1, 0);
dfs2(1, 0); for(int i = 1; i <= n; i++) {
printf("%d\n", max(dp[i][0], dp[i][2]));
}
} return 0;
}
求树上任意一点所能到达的最远距离 - 树上dp的更多相关文章
- xdoj-1319 求树上任意一点的最大距离----利用树的直径
1 #include <bits/stdc++.h> using namespace std; ; vector < vector <int> > g(N); in ...
- hdu-2196 树形dp 求一个树中所有节点能到达的最远距离f[i] (其实也不难嘛!)
#include <bits/stdc++.h> using namespace std; ; struct T { int to; int w; }; vector < vecto ...
- HDU 2196 求树上所有点能到达的最远距离
其实我不是想做这道题的...只是今天考试考了一道类似的题...然后我挂了... 但是乱搞一下还是有80分....可惜没想到正解啊! 所以今天的考试题是: 巡访 (path.pas/c/cpp) Cha ...
- Bellman_Ford算法(求一个点到任意一点的最短距离)
单源最短路问题是固定一个起点,求它到任意一点最短路的问题. 记从起点出发到顶点 i 的最短距离为d[i],则有以下等式成立 d[i]=min{d[j]+(从j到 i 的边的权值) 看代码 #inclu ...
- HDU 2376 树形dp|树上任意两点距离和的平均值
原题:http://acm.hdu.edu.cn/showproblem.php?pid=2376 经典问题,求的是树上任意两点和的平均值. 这里我们不能枚举点,这样n^2的复杂度.我们可以枚举每一条 ...
- caioj 1237: 【最近公共祖先】树上任意两点的距离 在线倍增ST
caioj 1237: [最近公共祖先]树上任意两点的距离 倍增ST 题目链接:http://caioj.cn/problem.php?id=1237 思路: 针对询问次数多的时候,采取倍增求取LCA ...
- 关于delphi点击webbrowser中任意一点的问题
关于delphi点击webbrowser中任意一点的问题 有时候我们需要delphi载入webbrowser1打开网页的时候 需要点击某一个点的位置 可能是坐标 可能是按钮 可能是其他的控件应该如何来 ...
- echarts 点击方法总结,点任意一点获取点击数据,在多图联动中用生成标线举例
关于点击(包括左击,双击,右击等)echarts图形任意一点,获取相关的图形数据,尤其是多图,我想部分人遇到这个问题一直很头大.下面我用举例说明,如何在多图联动基础上,我们点击点击任意一个图上任意一点 ...
- HDU 5723 Abandoned country(kruskal+dp树上任意两点距离和)
Problem DescriptionAn abandoned country has n(n≤100000) villages which are numbered from 1 to n. Sin ...
随机推荐
- java Class中得到构造方法Constructor、方法Method、字段Field
常用方法: Constructor类用于描述类中的构造方法: Constructor<T> getConstructor(Class<?>... parameterTypes) ...
- linux主编号的动态分配
一些主设备编号是静态分派给最普通的设备的. 一个这些设备的列表在内核源码树的 Documentation/devices.txt 中. 分配给你的新驱动使用一个已经分配的静态编号的机会 很小, 但是, ...
- SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
本次的项目环境为 SpringBoot 2.0.4, JDK8.0. 服务器环境为CentOS7.0, Nginx的忘了版本. 前言 SpringBoot使用MultiPartFile接收来自表单的f ...
- H3C VLAN基本配置
- tab选项卡平滑滚动vue
<html lang="en"> <head> <meta charset="UTF-8"> <title>Ti ...
- c#链接redis用户名密码
方法一 使用:ServiceStack.Redis 在ip:port前面加上@用来表示密码,比如password@ip:port <add key="RedisServer" ...
- pyinstaller打包exe文件闪退的解决办法
pyinstaller是python下目前能打包py文件为windows下的exe文件的一个非常友好易用的库!但是,小爬每次用pyinstaller打包时也总是遇到一些难题,有时网上搜了一圈,也没看到 ...
- 叶子的颜色---经典树上dp
挺简单的一个dp #include<iostream> #include<cstring> #include<cstdio> #include<algorit ...
- Python学习3月5号【python编程 从入门到实践】---》笔记
---恢复内容开始--- 1.变量 一.只能包含字母.数字.下划线.****不能以数字开头作变量 二.不能包含空格, 三.不要将python关键字和函数名用作变量名 四.最好能有描述性和简短的特征 五 ...
- 中小型企业级 IPS 部署
<构建基于Snort+Guardian+Iptables的IPS> 2020年的第三天,依旧如往常写文章,分享最近做的项目继<中小型企业级防火墙部署>之后的另一部分<构建 ...