题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196

Problem Description
A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information. 
Input
Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
Output
For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
Sample Input
5
1 1
2 1
3 1
1 1
 
Sample Output
3 2 3 4 4

总算彻底理解这个题了 =.=

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=; struct Edge
{
int v;
int len;
int next;
} edge[maxn<<]; int head[maxn];
int fm[maxn],fn[maxn]; ///最远距离,以及对应的子树的序号
int sm[maxn],sn[maxn]; ///次远距离,以及其对应的子树
int k; void addedge(int u,int v,int l)
{
edge[k].v=v;
edge[k].len=l;
edge[k].next=head[u];
head[u]=k++; edge[k].v=u;
edge[k].len=l;
edge[k].next=head[v];
head[v]=k++;
} void dfs1(int u,int p) ///第一次dfs找到子树种最大的长度,和最大长度的子树的序号
{
fm[u]=; ///初始化
sm[u]=;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dfs1(v,u);
if(edge[i].len+fm[v]>sm[u])
{
sm[u]=edge[i].len+fm[v];
sn[u]=v;
if(sm[u]>fm[u])
{
swap(fm[u],sm[u]);
swap(fn[u],sn[u]);
}
}
}
} void dfs2(int u,int p)
{
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
if(v==fn[u])
{
if(edge[i].len+sm[u]>sm[v])
{
sm[v]=edge[i].len+sm[u];
sn[v]=u; ///开始没懂为什么还要记录结点
if(sm[v]>fm[v]) ///更新的目的就是可以找到从子树来的最大值,不记录有时候找的是次大值
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
else
{
if(edge[i].len+fm[u]>sm[v])
{
sm[v]=edge[i].len+fm[u];
sn[v]=u;
if(sm[v]>fm[v])
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
dfs2(v,u);
}
} int main()
{
int n;
while(scanf("%d",&n)==)
{
memset(head,-,sizeof(head));
k=;
int x,l;
for(int i=; i<=n; i++)
{
scanf("%d%d",&x,&l);
addedge(i,x,l);
}
dfs1(,-); ///随便选一点作为树根,那么他的父亲结点就设为-1
dfs2(,-); ///所以换成dfs1(2,-1),dfs2(2,-1) 也是可以的
for(int i=; i<=n; i++)
printf("%d\n",fm[i]);
}
return ;
}

hdu2196 树形dp的更多相关文章

  1. hdu2196 树形dp经典|树的直径

    /* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...

  2. hdu2196树形dp

    有一棵树,找每个节点所能到达的最远距离是多少 dis[u][0]正向最大距离    dis[u][1]正向次大距离     dis[u][2]反向最大距离 先一边dfs求出每个节点的正向最大距离(就是 ...

  3. Computer(HDU2196+树形dp+树的直径)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...

  4. hdu-2196 树形dp 求一个树中所有节点能到达的最远距离f[i] (其实也不难嘛!)

    #include <bits/stdc++.h> using namespace std; ; struct T { int to; int w; }; vector < vecto ...

  5. 【树形dp小练】HDU1520 HDU2196 HDU1561 HDU3534

    [树形dp]就是在树上做的一些dp之类的递推,由于一般须要递归处理.因此平庸情况的处理可能须要理清思路.昨晚開始切了4题,作为入门训练.题目都很easy.可是似乎做起来都还口以- hdu1520 An ...

  6. HDU2196 Computer(树形DP)

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

  7. HDU5834 Magic boy Bi Luo with his excited tree(树形DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...

  8. Codeforces 543D Road Improvement(树形DP + 乘法逆元)

    题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...

  9. POJ3162 Walking Race(树形DP+尺取法+单调队列)

    题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...

随机推荐

  1. python对Mysql操作和使用ORM框架(SQLAlchemy)

    python对mysql的操作 Mysql 常见操作 数据库操作 创建数据库 create database fuzjtest 删除数据库 drop database fuzjtest 查询数据库 s ...

  2. linux 安装 ArcSDE10.1

    实验仍未成功,步骤仅供参考. 1:首先检查一下在Linux操作系统下Oracle数据库是否能启动,是否能连通等 [oracle@localhost ~]$ sqlplus SQL*Plus: Rele ...

  3. Java学习笔记13---一个循环程序的设计范例

    package welcome; import java.util.Scanner; /* * 一个循环程序的设计范例 * 首先编写仅执行一次的程序(当无循环时) * 循环的设计步骤: * 1.确定程 ...

  4. RAID技术介绍

    RAID技术介绍 简介 RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAI ...

  5. Path Sum

    需如下树节点求和 5  /  \ 4     8  /     /  \ 11  13    4 / \     /  \  7    2      5   1 JavaScript实现 window ...

  6. vijos1404 遭遇战

    描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC的人誓死不屈,即将于恐怖分子展开激战,准备让一个人守着A区,这样恐怖分子就不能炸掉服务器了.(一 ...

  7. java表格操作之设置表格列宽

    设置所有列的宽度 /** * 设置所有列的列宽 * @param table * @param width */ public void setAllColumnWidth(JTable table, ...

  8. #define #include #undef的其中一个用法(目的)

    一.背景 最近在跟一段系统级的代码,和原来单纯的下位机代码相比,真的是刘姥姥进大观园--看花了眼.相较于 之前所常见的各种下位机代码,系统级代码常常会出现深层次结构体嵌套,结构体内的各种回调函数导致对 ...

  9. 逻辑思维面试题-java后端面试-遁地龙卷风

    (-1)写在前面 最近参加了一次面试,对笔试题很感兴趣,就回来百度一下.通过对这些题目的思考让我想起了建模中的关联,感觉这些题如果没接触就是从0到1,考验逻辑思维的话从1到100会更好,并且编程简易模 ...

  10. ReflectionToStringBuilder类

    ReflectionToStringBuilder类是用来实现类中的toString()方法的类,它采用Java反射机制(Reflection),通过reflection包中的AccessibleOb ...