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个点染成白色.将所有点染色后,你会获得 ...
随机推荐
- 查询各个商品分类中各有多少商品的SQL语句
SELECT goods_category_id ,count(*) FROM `sw_goods` group by goods_category_id
- 后台首页品字形(frameset)框架搭建
get_defined_constants([true])//显示所有常量信息.参数true,表示分组显示,查看当前系统给我提供了哪些常量可以使用,包括自定义常量. __CONTROLLER__//获 ...
- shell+curl监控网站页面(域名访问状态),并利用sedemail发送邮件
应领导要求,对公司几个主要站点的域名访问情况进行监控.下面分享一个监控脚本,并利用sendemail进行邮件发送. 监控脚本如下:下面是写了一个多线程的网站状态检测脚本,直接从文件中读出站点地址,然后 ...
- ES6新增const常量、let变量
JavaScript 严格模式(use strict) 严格模式下你不能使用未声明的变量. const c1 = 1; const c2 = {}; const c3 = []; 不能对c1的值进行再 ...
- 对window的认识
首先要明确: 不管是全局的函数还是全局的变量,都是属于window的,例如: a = 12; //全局变量 alert(a) === alert(window.a) function show(){ ...
- 1445 送Q币
1445 送Q币 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 一次在玩网络游戏的过程中,在 ...
- usb驱动开发8之配置描述符
前面分析了usb的四大描述符之端点描述符,接口描述符(每一个接口对应一个功能,与之配备相应驱动),下面是看配置描述符还是看设备描述符呢??我们知道,设备大于配置,配置大于接口,接口可以有多种设置. 我 ...
- delphi数组作为参数传值
在函数中如果数组的个数不定,可以使用开放数组参数 实参可以接受静态数组和动态数组 procedure p1(a:array of Byte); begin ShowMessage( IntToHex( ...
- Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...
- SpringMVC中的@PathVariable
@PathVariable是用来动态获得url中的参数的,代码示例如下: 可以在代码中获得lev_1.lev_2和target参数的值看一下 // 支持跳转到WEB-INF/目录下二层目录 @Requ ...