求树上任意一点所能到达的最远距离 - 树上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 ...
随机推荐
- 2019-11-6-Roslyn-how-to-use-WriteLinesToFile-to-write-the-semicolons-to-file
title author date CreateTime categories Roslyn how to use WriteLinesToFile to write the semicolons t ...
- P1048 数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 输入格式 第一行包含一个整数 \(n\) ,表示数组中的元素个数 ...
- WPF 一个性能比较好的 gif 解析库
本文介绍 Magick.NET ,这是 ImageMagick 的 .Net 封装,他支持 100 多种格式的图片,而 gif 也是他支持的.本文告诉大家如何使用这个库播放 gif 图 先给大家看一下 ...
- background:url(./images.png) no-repeat 0 center的用法
background:url(./images.png) no-repeat 0 center; //图像地址 不重复 水平位置0 垂直位置居中 background:url(./images.png ...
- Linux 内核 低级 sysfs 操作
kobject 是在 sysfs 虚拟文件系统之后的机制. 对每个在 sysfs 中发现的目录, 有一个 kobject 潜伏在内核某处. 每个感兴趣的 kobject 也输出一个或多个属性, 它出现 ...
- dll中全局变量在外部进行引用
在Windows中实际导出全局变量,您必须使用类似于export / import语法的语法,例如: #ifdef COMPILING_THE_DLL #define MY_DLL_EXPORT ex ...
- Trie 树的一些题
Trie 树的一些题 牛客练习赛11 假的字符串 (Trie树+拓扑找环) 链接:https://ac.nowcoder.com/acm/problem/15049 来源:牛客网 给定n个字符串,互不 ...
- Linux 2>&1的意思
2>&1的意思是将标准错误(2)也定向到标准输出(1)的输出文件中. 我们来具体了解下:Linux 中三种标准输入输出,分别是STDIN,STDOUT,STDERR,对应的数字是0,1, ...
- 第二阶段:2.商业需求文档MRD:2.MRD-目标市场分析
版本管理的变更人,属性,时间以及审核人都要严格的写清楚. MRD主要面向的是参与这个需求同级别的同时或主管,让大家更好的了解这个产品的各个方面,达成共识. 现在互联网的发展周期很短,不需要看4.5年, ...
- 函数闭包模拟session
根据上一个认证功能的问题 要解决的就是只需要登录一次 也就是登录一次之后的用户名跟密码可以保存下来让其他函数用-->全局变量 user_dic = {"user_name": ...