题意:

这题想了挺久的, 参考了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(求树上每个点的最长距离)的更多相关文章

  1. hdu 2196(求树上每个节点到树上其他节点的最远距离)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 思路:首先任意一次dfs求出树上最长直径的一个端点End,然后以该端点为起点再次dfs求出另一个 ...

  2. HDU 2196 Computer (树dp)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 给你n个点,n-1条边,然后给你每条边的权值.输出每个点能对应其他点的最远距离是多少 ...

  3. 题解报告:hdu 2196 Computer(树形dp)

    Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du ...

  4. HDU 2196 Computer(求树上每一个节点到其他点的最远距离)

    解题思路: 求出树的直径的两个端点.则树上每一个节点到其它点的最远距离一定是到这两个端点的距离中最长的那一个. #include <iostream> #include <cstri ...

  5. HDU 2196 Computer (树上最长路)【树形DP】

    <题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与 ...

  6. HDU 2196 Computer( 树上节点的最远距离 )

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. hdu 2196 Computer 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem ...

  9. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

随机推荐

  1. android 多线程 AsyncTask 下载图片

    AsyncTask 下载图片 package com.test.network; import android.graphics.Bitmap; import android.graphics.Bit ...

  2. WOW.js 动画使用

    有的页面在向下滚动的时候,有些元素会产生细小的动画效果.虽然动画比较小,但却能吸引你的注意.比如刚刚发布的 iPhone 6 的页面(查看).如果你希望你的页面也更加有趣,那么你可以试试 WOW.js ...

  3. 莫比乌斯函数 && HDU-1695

    莫比乌斯函数定义: $$\mu(d)=\begin{cases}1 &\text{d = 1}\\(-1)^r &\text{$d=p_1p_2...p_r,其中p_i为不同的素数$} ...

  4. 2019/05/11 JAVA虚拟机原理堆、栈、方法区概念区别

    Java堆 堆内存用于存放由new创建的对象和数组.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对 ...

  5. ubuntu安装mysql多实例

    想要尝试mysql的读写分离,在云上安装完mysql之后突然想到一个问题:我本机是没有公网IP的. 开始尝试在唯一一台云服务器上安装多个mysql实例. 主要步骤: 1.新建MySQL目录 (1):新 ...

  6. OCP 11g 第一章练习

    练习 1-1 研究所在环境的DBMS 这是一个书面练习,没有具体的解决方案. 确定自己所在环境使用的应用程序, 应用服务器 , 和数据库. 然后集中精力研究数据库, 体验一下数据库的规模和忙碌程度. ...

  7. laravel中的队列

    Laravel 队列为不同的后台队列服务提供统一的 API,可使用多种驱动,eg:mysql,redis,Beanstalkd等,驱动已经封装,不需要管理这些驱动,只需要修改配置就可以更改驱动,在驱动 ...

  8. MFC技术积累——基于MFC对话框类的那些事儿4

    3.3.4 借助兼容DC加载DIB位图 创建一个与设备环境相兼容的DC,通过将位图暂时导入至兼容DC,然后利用CDC::BitBlt 或者CDC::StretchBlt函数将位图绘制到设备环境中. 示 ...

  9. HDU 4281 (状态压缩+背包+MTSP)

    Judges' response Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. liunx 中安装mysql 图形界面 phpmyadmin

    是浏览器图形界面 1. 安装mysql 图形管理工具. 2. 使用phpmyadmin 图像化工具. 3.下载地址  http://www.phpmyadmin.net/ 4. 查看是否安装这两个包 ...