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

思路:

一看就是一道树形DP的题目,对于一个节点来说,到它的最远距离的路径可能来于子树,也可能来源于经过父亲节点的路径,所以我们两次DFS即可。

第一次DFS自底向上(从叶节点开始),依次求出每个节点的在其子树上的最大距离和次大距离

第二次DFS自顶向下(从根节点开始),通过比较经过父亲节点的路径的最大距离和来源于子树的最大距离比较然后更新最大距离

至于为什么要保存次大距离呢??因为经过父亲节点的最大距离可能刚好经过当前的孩子节点,那么我们就只能通过当前孩子到父亲节点的距离加上经过父亲节点的路径次大值和当前节点的位于其子树的路径的最大距离的比较来更新最大距离咯。

虽然思路还是比较清晰的,自己实现起来还是比较难的。。。。

代码如下:

 #include<cstdlib>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
#define MAX 10010
class node
{
public:
int to;
int w;
int next; };
node edge[*MAX];
int head[MAX];
int tol;
int maxn[MAX];
int smaxn[MAX];
int m_id[MAX];
int sm_id[MAX];
int vis[MAX];
void init()
{
memset(head,-,sizeof(head));
memset(maxn,,sizeof(maxn));
memset(smaxn,,sizeof(smaxn));
memset(vis,,sizeof(vis));
tol=;
}
void Build_Tree(int u,int v,int w)
{
edge[tol].to=v;
edge[tol].w=w;
edge[tol].next=head[u];
head[u]=tol++;
}
void dfs1(int root,int parent)
{
vis[root]=;
for(int i=head[root];i!=-;i=edge[i].next)
{
if(vis[edge[i].to]) continue;
int son=edge[i].to;
dfs1(son,root);
int len=edge[i].w;
if(smaxn[root]<maxn[son]+len)
{
smaxn[root]=maxn[son]+len;
sm_id[root]=son;
if(smaxn[root]>maxn[root])
{
swap(smaxn[root],maxn[root]);
swap(sm_id[root],m_id[root]);
}
}
}
}
void dfs2(int root ,int parent)
{
for(int i=head[root];i!=-;i=edge[i].next)
{
if(edge[i].to==parent) continue;
int son=edge[i].to;
if(m_id[root]==son)
{
if(edge[i].w+smaxn[root]>smaxn[son])
{
smaxn[son]=edge[i].w+smaxn[root];
sm_id[son]=root;
if(smaxn[son]>maxn[son])
{
swap(smaxn[son],maxn[son]);
swap(sm_id[son],m_id[son]);
}
}
}
else
{
if(edge[i].w+maxn[root]>smaxn[son])
{
smaxn[son]=edge[i].w+maxn[root];
sm_id[son]=root;
if(smaxn[son]>maxn[son])
{
swap(smaxn[son],maxn[son]);
swap(m_id[son],sm_id[son]);
}
}
}
dfs2(son,root);
} }
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<=n;i++)
{
int u,w;
scanf("%d%d",&u,&w);
Build_Tree(i,u,w);
Build_Tree(u,i,w);
}
dfs1(,-);
dfs2(,-);
for(int i=;i<=n;i++)
cout<<maxn[i]<<endl; }
return ;
}

hdu2196Computer 树形DP的更多相关文章

  1. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  2. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  3. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  7. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  8. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  9. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

随机推荐

  1. nfs服务端配置文件详解

    配置参数语法 配置文件路径 /etc/exports 可以使用#进行注释说明 一个完整的配置实例至少需要3个参数 1.被共享的目录 必须是存在的目录 2.向谁共享 可以指定主机或网络范围,支持通配符* ...

  2. sql 语句写的行列转换

    以前面试老遇到一个行列转换的问题,今天没事,顺便记录一下 假设有这样一张表,如下图,创建表就不说了,直接建或者SQL语句都行 sql语句如下 --第一种 select name as 姓名, max( ...

  3. Legendary Items-微软实习生笔试第一题

    题目如下: 这道题难点不仅在于正确理解题意,判断递归条件,更在于用数学方法推出解决公式.因为N最大为1百万,而内存只有256MB, 所以暴力递归肯定会超时,超空间. 不过,我才疏学浅,又没有大量时间去 ...

  4. JSAAS的Activiti会签开发扩展处理

    1.什么是会签? 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字.在流 ...

  5. Java Level 2 学习的八大名著

    Java Level 2 学习的八大名著 前段时间有几天难得的假期,于是把自己认为Java技术栈中的精华总结了一下,但是一直没有时间写下来,今天终于得空希望本文可以对大家有所启发.通过多个实际项目的沉 ...

  6. 职责链模式(Chain of Responsibility)的Java实现

    职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 ...

  7. Timer,TimerTask通过程序计数器实现的定时任务

    1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看 做是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里(仅是概念模型, 各种虚 ...

  8. iterable

    iterable 阅读: 148111 遍历Array可以采用下标循环,遍历Map和Set就无法使用下标.为了统一集合类型,ES6标准引入了新的iterable类型,Array.Map和Set都属于i ...

  9. 多云时代,海外微软Azure云与国内阿里云专线打通性能测试

    本文地址:http://www.cnblogs.com/taosha/p/6528730.html 在云计算的大时代,大型客户都有业务全球拓展的需求,考虑到成本,时间因素,一般都是选择云计算,现在云计 ...

  10. 第一章 自定义MVC框架

    第一章  自定义MVC框架1.1 MVC模式设计    组成:Model:模型,用于数据和业务的处理          View :视图,用于数据的显示          Controller:控制器 ...