求树上任意一点所能到达的最远距离 - 树上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 ...
随机推荐
- 【React】react项目引入echarts插件 K线图
参考npm文档:https://www.npmjs.com/package/echarts-for-react 由于npm上已经有针对react项目出的echarts插件,所以在这里直接安装 第一步: ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- redis常用指令总结以及功能介绍
第一部分 redis的常用指令 一.针对key的操作 1.1 del key [key .. ] , 删除指定的一个或者多个key;1.2 dump key ...
- UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]
解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...
- liunx重定向控制台消息
Linux 在控制台记录策略上允许一些灵活性, 它允许你发送消息到一个指定的虚拟控制台 (如果你的控制台使用的是文本屏幕). 缺省地, 这个"控制台"是当前虚拟终端. 为了选择 一 ...
- 机器学习——集成学习之Boosting
整理自: https://blog.csdn.net/woaidapaopao/article/details/77806273?locationnum=9&fps=1 AdaBoost GB ...
- 用es5实现模板字符串
废话不多说,主要是利用正则表达式replace+eval动态取值(纯属娱乐) String.prototype.myReplace = function(){ return this.replace( ...
- ORACLE禁用和启用外键
禁用外键 select 'alter table '|| t.table_name||' disable constraint '||t.constraint_name||';' from user_ ...
- 安装低版本Microsoft .NET Framework 4.5受阻解决方案
在VS目标框中找不到Microsoft .NET Framework 4.5,项目出错,安装受阻.... 1.Microsoft .NET Framework 安装了高版本后,低版本通过网上上下载的d ...
- Visual Studio Team Services使用教程【3】:默认团队权限说明
2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visual Studio Team Services(VSTS)与敏捷开发ALM实战关键报告( ...