求树上任意一点所能到达的最远距离 - 树上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 ...
随机推荐
- Spring Boot笔记之邮件(spring-boot-starter-mail)
Spring Boot环境中发送邮件 pom.xml引入`spring-boot-starter-mail` application.yml配置 163邮箱 QQ邮箱 Gmail邮箱 发送邮件 ser ...
- JavaScript数据类型总结
1. 六种简单数据类型:Undefined.Null.Boolean.Number.String.Symbol(新增): 一种复杂数据类型:Object: (1)基本数据类型保存在栈内存中,是按值传 ...
- linux strace 命令
有时小问题可以通过观察用户空间的应用程序的行为来追踪. 监视程序也有助于建立对驱 动正确工作的信心. 例如, 我们能够对 scull 感到有信心, 在看了它的读实现如何响应 不同数量数据的读请求之后. ...
- H3C 指定下次启动加载的应用程序文件
- Date日期时间相关
最近在封装一个关于时间函数的功能时,竟发现这些最基本的函数都有些生疏,于是进来来总结复习下,巩固自己记忆的同时,希望能帮助到需要的人 首先了解下日期对象相关的方法 var date = new Dat ...
- python调用另一个文件中的代码,pycharm环境下:同文件夹下文件(.py)之间的调用,出现红线问题
如何调用另一个python文件中的代码无论我们选择用何种语言进行程序设计时,都不可能只有一个文件(除了“hello world”),通常情况下,我们都需要在一个文件中调用另外一个文件的函数呀数据等等, ...
- 【Linux】Terminal中输入一行命令快速移动光标至行首行尾
Linux: ①快速移动光标至行首 Home或Ctrl+A ②快速移动光标至行尾 End或Ctrl+E ③从光标处开始删除,直到行尾 Ctrl+K ④到下一行 Ctrl+N 或 方向键:↓ ⑤到上一行 ...
- C# 获取控制台程序路径
- 21.time和random
原文:https://www.cnblogs.com/yuanchenqi/article/5732581.html time模块 三种时间表示 在Python中,通常有这几种方式来表示时间: 时间戳 ...
- Jmeter阶梯加压监听
巧用beanshell,做阶梯加压监听 1. 首先先添加阶梯加压线程组 bzm - Concurrency Thread Group 设置阶梯加压值,目标最大并发用户为80,加速步率时长为100秒, ...