HDU2196computer(树上最远距离 + DP)
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4990 Accepted Submission(s): 2509
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.
1 1
2 1
3 1
1 1
2
3
4
4
题意:以1为根,建立一棵树,每个节点之间的长度为len,然后求每个节点到叶子的最远距离;
分析:求i节点,两种可能,一种是从i的子树得到最远距离,第二种是从父节点得到最远距离,所以两次dfs,第一次统计所有节点从子树到叶子的最远距离和次远距离,第一次看这道题,不明白次远距离有什么用,看到第二次dfs就明白了,第二次就要判断i是从子树还是父节点过来的,此时已经求出了子树方向的所有最长距离,最要知道父节点方向最长距离就ok了,比较一下嘛,然后父节点的最远距离有两种可能,一种是经过 i 而来的,所以求 i 父节点方向的最远距离就是 i 父节点的次最远距离了,第二种是不经过 i 而来的,所以 i 父节点方向的最远距离就是他
----------------------------------------------------------------------------
2016/3/17更新
今天又看了一遍好费劲,其实第一次dfs1主要是求了根节点1到左右两边节点的最远距离,一个最远,一个次远,然后第二次还是从根节点dfs2,主要就是判断每一个点是从子树来的还是从父节点来的,所以先判断根节点的儿子,因为根节点已经在第一部求出来了到两边的距离。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max = + ;
struct Node
{
int to,next,len;
};
Node edge[ * Max];
int head[Max], tol;
int maxn[Max],maxnId[Max]; //最远距离和最远距离对应的序号
int smaxn[Max],smaxnId[Max]; //次远距离和次远距离对应的序号
void add_edge(int a, int b, int len)
{
edge[tol].to = b;
edge[tol].next = head[a];
edge[tol].len = len;
head[a] = tol++;
}
void dfs1(int u, int p)
{
maxn[u] = smaxn[u] = ;
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v == p) //如果是父节点跳过
continue;
dfs1(v, u);
if(smaxn[u] < maxn[v] + edge[i].len) //如果子节点的最远距离大于次远距离,就更新次远距离;先更新次远距离,由次远距离和最远距离比较更新最远距离
{
smaxn[u] = maxn[v] + edge[i].len;
smaxnId[u] = v;
if(smaxn[u] > maxn[u])
{
swap(smaxn[u], maxn[u]);
swap(smaxnId[u], maxnId[u]);
}
}
}
}
void dfs2(int u, int p)
{
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v == p)
continue;
if(v == maxnId[u]) //如果父节点方向最远距离经过这个子节点
{
if(smaxn[u] + edge[i].len > smaxn[v]) //选择次远距离,因为最远距离经过v点
{
smaxn[v] = smaxn[u] + edge[i].len;
smaxnId[v] = u;
if(maxn[v] < smaxn[v])
{
swap(maxn[v], smaxn[v]);
swap(maxnId[v], smaxnId[v]);
}
}
}
else
{
if(maxn[u] + edge[i].len > smaxn[v])
{
smaxn[v] = maxn[u] + edge[i].len;
smaxnId[v] = u;
if(maxn[v] < smaxn[v])
{
swap(maxn[v], smaxn[v]);
swap(maxnId[v], smaxnId[v]);
}
}
}
dfs2(v, u);
}
}
int main()
{
int n,v,len;
while(scanf("%d", &n) != EOF)
{
tol = ;
memset(head, -, sizeof(head));
for(int i = ; i <= n; i++)
{
scanf("%d%d", &v, &len);
add_edge(i, v, len);
add_edge(v, i, len);
}
dfs1(, -); //向下
dfs2(, -);
for(int i = ; i <= n; i++)
printf("%d\n", maxn[i]);
}
return ;
}
HDU2196computer(树上最远距离 + DP)的更多相关文章
- 洛谷P1273 有线电视网 树上分组背包DP
P1273 有线电视网 )逼着自己写DP 题意:在一棵树上选出最多的叶子节点,使得叶子节点的值 减去 各个叶子节点到根节点的消耗 >= 0: 思路: 树上分组背包DP,设dp[u][k] 表示 ...
- 基于在树上走的DP问题
笔者已经很久没有打过题解了,如果打题解,就总是要连着一个知识点来打题解. 最近做过一共两道这样的题目.笔者认为这样的题有较强的可拓展性,比较有意义. 所以就打一篇博客. 问题概述 先说说这是个什么样的 ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- HDU-2196-Computer(树上DP)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=2196 题意: A school bought the first computer some time ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- 【BZOJ4033】[HAOI2015]树上染色 树形DP
[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...
- hdu 4123 Bob’s Race (dfs树上最远距离+RMQ)
C - Bob’s Race Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Subm ...
- 『树上匹配 树形dp』
树上匹配 Description 懒惰的温温今天上班也在偷懒.盯着窗外发呆的温温发现,透过窗户正巧能看到一棵 n 个节点的树.一棵 n 个节点的树包含 n-1 条边,且 n 个节点是联通的.树上两点之 ...
- 【HAOI2015】树上染色—树形dp
[HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...
随机推荐
- iOS之block
1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...
- python socket发送魔法包网络唤醒开机.py
python socket发送魔法包网络唤醒开机.py 现在的电脑应该都普遍支持有线网络的WOL了,支持无线网络唤醒的电脑,可能比较少. """ python socke ...
- Windows Phone:自定义字体在xaml和代码中使用
最近,我的小应用<认字>更新了一个能发声的版本,朋友对Speech做读音没有兴趣,反而对其中使用的楷体文字表示了兴趣,也许Speech的文章比较多,这次我对这个自定义字体在xaml和代码中 ...
- 好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面)
转载:http://www.cnblogs.com/lyhabc/p/3322437.html 挺好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面) 这个工具主要就是 ...
- c++中二进制和整数转化
#1,包含文件 #include<bitset> #2,整数转化成二进制 int a = 63; bitset<6> bs(a); #3,二进制转化成整数 int b = bs ...
- 实现chrome扩展启动本地进程 - 补充
实现chrome扩展启动本地进程 - 补充 标签: chrome扩展启动本地程序访问本地磁盘 2014-10-17 11:42 6753人阅读 评论(17) 收藏 举报 分类: Chrome Plu ...
- 自定义GrildView实现单选功能
首先看实现功能截图,这是一个自定义Dialog,并且里面内容由GrildView 绑定数据源,实现类似单选功能. 首先自定义Dialog,绑定数据源 自定义Dialog弹出框大小方法 最主要实现的就是 ...
- myeclipse 2014新建maven web 项目步骤
首先在myeclipse中配置maven的安装路径: 在pom.xml中加上: 1 2 3 4 5 6 7 8 9 10 <plugins> <plugin&g ...
- 学习笔记——Maven实战(一)坐标规划
坐标是什么?为什么要规划? 坐标是Maven最基本的概念,它就像每个构件的身份证号码,有了它我们就可以在数以千万计的构件中定位任何一个我们感兴趣的构件.举个最简单的例子,如果没有坐标,使用JUnit的 ...
- JavaScript原型链和instanceof运算符的暧昧关系
时间回到两个月前,简单地理了理原型链.prototype以及__proto__之间的乱七八糟的关系,同时也简单了解了下typeof和instanceof两个运算符,但是,anyway,试试以下两题: ...