HDU 2196 Computer(求树上每个点的最长距离)
题意:
这题想了挺久的, 参考了kuangbin大神的代码:https://www.cnblogs.com/kuangbin/archive/2012/08/28/2659915.html
给出树上边的长度, 求出每一个点的最长距离(就是求这个点到某一个叶子结点的距离, 这个距离最长)。
分析:
结点u的最长路径, 其实就是max( u到子树叶子的最长路径, u到父亲的距离 + 父亲子树的最长路径).
注意, 因为父亲子树的最长路径可能会经过u, 这样这个状态就不能用 u到父亲的距离 + 父亲子树的最长路径表示。
所以记录每个节点的最长路和次长路。
用两次dfs求解。
第一次dfs求出每个点只看子树的最长距离和次长距离。(只关注结点本身)
第二次dfs求出每个孩子结点的最长距离(答案)。(关注结点的孩子)
松弛条件可以看代码。
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std; const int maxn = + ;
const int inf = 1e9 + ;
int Max[maxn];// 最大距离
int sMax[maxn];// 次大距离
int Id[maxn];// 最大距离对应序号
int sId[maxn];// 次大距离对应序号
struct Edge {
int v, d;
};
vector<Edge> G[maxn];
int N;
void init() {
for(int i = ; i < maxn; i ++) {
G[i].clear();
}
}
void dfs1(int u, int pre) {//更新u本身
Max[u] = sMax[u] = ;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v, d = G[u][i].d;
if(v == pre)
continue; //不经过父亲, 只搜索子树
dfs1(v, u); //一直搜到叶子再回溯, 因为是根据孩子的Max更新自己的Max
if(sMax[u] < Max[v] + d) { //如果u的次长距离 < 到v的距离 + v的最大距离
//更新距离
sMax[u] = Max[v] + d;
sId[u] = v;
if(sMax[u] > Max[u]) { //如果次长距离大于最长距离, 交换二者位置
swap(sMax[u], Max[u]);
swap(sId[u], Id[u]);
}
}
}
}
int dfs2(int u, int pre) {//更新u的孩子
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v, d = G[u][i].d;
if(v == pre)
continue; //同样不经过父亲
if(v == Id[u]) { //如果v在u的最长路径上
if(sMax[u] + d > sMax[v]) { //看看u的次长路 + d 是否> v的次长路
sMax[v] = sMax[u] + d;
sId[v] = u;
if(sMax[v] > Max[v]) { //如果次长距离大于最长距离, 交换二者位置
swap(sMax[v], Max[v]);
swap(sId[v], Id[v]);
}
}
} else { // v不在u的最长路径上
if(d + Max[u] > sMax[v]) { //试着更新v
sMax[v] = d + Max[u];
sId[v] = u;
if(sMax[v] > Max[v]) { //如果次长距离大于最长距离, 交换二者位置
swap(sMax[v], Max[v]);
swap(sId[v], Id[v]);
}
}
}
dfs2(v, u);
}
}
int main() {
while(cin >> N) {
init();
for(int i = ; i <= N; i++) {
int u, v, d;
cin >> v >> d;
G[i].push_back((Edge){v,d});
G[v].push_back((Edge){i,d});
}
dfs1(, -); dfs2(, -); for(int i = ; i <= N; i++) {
cout << Max[i] << "\n";
}
}
return ;
}
HDU 2196 Computer(求树上每个点的最长距离)的更多相关文章
- hdu 2196(求树上每个节点到树上其他节点的最远距离)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 思路:首先任意一次dfs求出树上最长直径的一个端点End,然后以该端点为起点再次dfs求出另一个 ...
- HDU 2196 Computer (树dp)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 给你n个点,n-1条边,然后给你每条边的权值.输出每个点能对应其他点的最远距离是多少 ...
- 题解报告:hdu 2196 Computer(树形dp)
Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du ...
- HDU 2196 Computer(求树上每一个节点到其他点的最远距离)
解题思路: 求出树的直径的两个端点.则树上每一个节点到其它点的最远距离一定是到这两个端点的距离中最长的那一个. #include <iostream> #include <cstri ...
- HDU 2196 Computer (树上最长路)【树形DP】
<题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与 ...
- HDU 2196 Computer( 树上节点的最远距离 )
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 2196 Computer 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDU 2196 Computer 树形DP经典题
链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...
随机推荐
- BFS HDOJ 1242 Rescue
题目传送门 题意:从r走到a,遇到x多走一步,问最小走到a的步数 分析:因为r有多个,反过来想从a走到某个r的最小步数,简单的BFS.我对这题有特殊的感情,去年刚来集训队时肉鸽推荐了这题,当时什么都不 ...
- 与Cookie相比,Web Storage存在的优势
与Cookie相比,Web Storage存在不少的优势,概括为以下几点:1. 存储空间更大:能提供5MB的存储空间(不同浏览器的提供的空间不同),Cookie仅4KB2. 存储内容不会发送到服务器: ...
- JAVA线程操作常见面试题 包括不使用内部类对多个线程加减1
class ManyThreads2 { private int j = 0; public synchronized void inc() { j++; System.out.println(Thr ...
- sass+compass起步
前言:Sass is an extension of CSS that adds power and elegance to the basic language. It allows you to ...
- 使用gitblit 在windows平台搭建git服务器
1.下载jdk,安装并且配置好环境变量 2.下载gitblit 直接解压无需安装 3.配置gitblit 1.修改gitblit安装目录下的data文件下的gitblit.properties.将in ...
- AJPFX总结private关键字
private关键字 什么是private关键字? 它是一个修饰符,代表私有的意思,它可以修饰成员变量和成员方法 private关键字的特点? ...
- Java GUI 基础组件
1.JLabel 标签 构造函数: JLabel() JLabel(String text) JLabel(String text,int align) //第二个参数设置文本的对齐方式,常 ...
- react ant design路由配置
最初的时候,只使用了antd中的menu,header和footer都是自己写的组件,在写路由时,总是报如下错误: 相关的路由配置如下: 在网上查的说是组件未暴露出去或者是return 这一行必须有个 ...
- Linux常用终端快捷键
UNIX程序员对键盘以及快捷键的设置都遵循一个标准:"手移动最少的距离,作更多的操作." 所有的类UNIX的终端上都有一些快捷键Ctrl+n = 下,Ctrl+b = 左,Ctrl ...
- http://blog.chinaunix.net/uid-9845710-id-1996675.html snmpd配置
http://blog.chinaunix.net/uid-9845710-id-1996675.html http://lihuipeng.blog.51cto.com/3064864/643960 ...