这道题搜了一晚上的题解,外加自己想了半个早上,终于想得很透彻了。于是打算好好写一写这题题解,而且这种做法比网上大多数题解要简单而且代码也比较简洁。

  首先要把题读懂,把输入读懂,这实际上是一颗有向树。第i(2≤i≤n)行的两个数u,d,其中u是i的父亲结点,d是距离。

  第一遍DFS我们可以计算出以u为根的子树中,距离u最远的结点的距离d(u, 0)以及次远的距离d(u, 1)。而且,这两个不在u的同一棵子树中,如果u只有一个孩子,那么d(u, 1) = 0

  第一遍DFS完以后,因为1是整棵树的跟,所以d(1, 0)就是距离1最远的距离。然后第二遍DFS,这次是用根的信息来更新它的子节点,此时d(u,0)d(u,1)的含义变为整棵树中距u最长和次长的距离。

  如图:

    红线代表距u最长的距离,绿线是次长。因为最长距离在v1的子树中,所以就用dis(u, v1) + d(u, 1)(也就是那条绿线)来更新距v1的最长和次长距离;    用dis(u, v2) + d(u, 0)(那条红线)来更新距v2的最长次长距离。

    因此最终答案就是d(u, 0)

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = + ;
vector<int> G[maxn], C[maxn];
int n; int d[maxn][]; void dfs(int u)
{
for(int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
dfs(v);
int t = d[v][] + C[u][i];
if(t > d[u][]) swap(t, d[u][]);
if(t > d[u][]) swap(t, d[u][]);
}
} void dfs2(int u)
{
for(int i = ; i < G[u].size(); i++)
{
int v = G[u][i], t, w = C[u][i];
if(d[v][] + w == d[u][]) t = w + d[u][];
else t = w + d[u][];
if(t > d[v][]) swap(t, d[v][]);
if(t > d[v][]) swap(t, d[v][]);
dfs2(v);
}
} int main()
{
scanf("%d", &n);
for(int u = ; u <= n; u++)
{
int v, d; scanf("%d%d", &v, &d);
G[v].push_back(u); C[v].push_back(d);
} dfs();
dfs2(); for(int i = ; i <= n; i++) printf("%d\n", d[i][]); return ;
}

代码君

SGU 149 树形DP Computer Network的更多相关文章

  1. HDU 2196 树形DP Computer

    题目链接:  HDU 2196 Computer 分析:   先从任意一点开始, 求出它到其它点的最大距离, 然后以该点为中心更新它的邻点, 再用被更新的点去更新邻点......依此递推 ! 代码: ...

  2. SGU 149. Computer Network( 树形dp )

    题目大意:给N个点,求每个点的与其他点距离最大值 很经典的树形dp...很久前就想写来着...看了陈老师的code才会的...mx[x][0], mx[x][1]分别表示x点子树里最长的2个距离, d ...

  3. 树形DP求树的重心 --SGU 134

    令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...

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

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

  5. computer(树形dp || 树的直径)

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

  6. 树形dp compare E - Cell Phone Network POJ - 3659 B - Strategic game POJ - 1463

    B - Strategic game POJ - 1463   题目大意:给你一棵树,让你放最少的东西来覆盖所有的边   这个题目之前写过,就是一个简单的树形dp的板题,因为这个每一个节点都需要挺好处 ...

  7. HDU2196 Computer(树形DP)

    和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...

  8. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  9. poj3417 Network 树形Dp+LCA

    题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...

随机推荐

  1. 新生代内存中为什么要有两个survivor区

    首先是关于新生代中的内存分布的描述: 新生代中的对象都是“朝生夕死”的对象,所以每次gc存活的对象很少,于是在新生代中采用的垃圾回收算法是“复制算法”. 将新生代的内存分为一块较大的Eden区域和两块 ...

  2. 530 Minimum Absolute Difference in BST 二叉搜索树的最小绝对差

    给定一个所有节点为非负值的二叉搜索树,求树中任意两节点的差的绝对值的最小值.示例 :输入:   1    \     3    /   2输出:1解释:最小绝对差为1,其中 2 和 1 的差的绝对值为 ...

  3. Less的学习和使用

    官网 http://less.bootcss.com/usage/ 在线编译器 http://tool.oschina.net/less

  4. JDk安装及环境变量的配置

    一.JDK的安装 1.打开下载好的安装包(我在这里附上一个百度云连接,https://pan.baidu.com/s/1o3nx0kbmecAISeneGqykLQ    提取码:jnw6) 傻瓜式安 ...

  5. 声明已被否决 VS C++

    error C4996声明已被否决,不止一次碰到这个问题,在这里必须mark一下! 尝试这个1.Project Properties > Configuration Properties > ...

  6. ios 自定义加载动画效果

    在开发过程中,可能会遇到各种不同的场景需要等待加载成功后才能显示数据.以下是自定义的一个动画加载view效果.      在UIViewController的中加载等到效果,如下 - (void)vi ...

  7. Actionbar Demo

    源码下载:http://download.csdn.net/detail/bx276626237/8874119

  8. MySQL分表操作的例子

    USE project;DROP PROCEDURE IF EXISTS project.delete_test_user;delimiter $$CREATE PROCEDURE project.d ...

  9. codevs 1992 聚会

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小S 想要从某地出发去同学k的家中参加一个party,但要有去有回.他想让所用的 ...

  10. uiviewcontroller 键盘不遮挡信息

    //添加监听事件 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow: ...