题目链接: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. JavaScript高级程序设计---学习笔记(一)

    今天,2017.3.17开始利用课余时间仔细学习<JavaScript高级程序设计>,将需要掌握的知识点记录下来,争取把书里的所有代码敲一遍并掌握. 1.标识符命名最好是第一个字母小写,剩 ...

  2. C#关于AutoResetEvent的使用介绍(用AutoResetEvent实现同步)

    前几天碰到一个线程的顺序执行的问题,就是一个异步线程往A接口发送一个数据请求.另外一个异步线程往B接口发送一个数据请求,当A和B都执行成功了,再往C接口发送一个请求.说真的,一直做BS项目,对线程了解 ...

  3. Nginx网站使用CDN之后禁止用户真实IP访问的方法

    做过面向公网WEB的运维人员经常会遇见恶意扫描.拉取.注入等图谋不轨的行为,对于直接对外的WEB服务器,我们可以直接通过 iptables .Nginx 的deny指令或是程序来ban掉这些恶意请求. ...

  4. linux 下的 mkfifo、exec 命令使用

    MKFIFOSection: User Commands (1)Updated: 1998年11月Index Return to Main Contents  NAME(名称)mkfifo - 创建F ...

  5. PL/SQL编程重点语句输出整理

    create or replace procedure pr_mytest is v_test number() :=; v_char varchar2():='数据库'; c_changl cons ...

  6. 关于VO中的Attribute的问题

    对于新手来说,有些时候会遇到VO中的Attribute的各种问题; 总结如下:1,你页面上输入了值,但是点击保存之后值并不能存到数据库,这个是因为该字段在VO中不是基于EO的  2,你将一个VO中的E ...

  7. python3基础之整数常用的方法整理

    希望对大家学习或者使用python3能具有一定的参考价值. __abs__     #返回一个数的绝对值 >>> num3=-22 >>> num3.__abs__ ...

  8. 【Electron】Electron开发入门(三):main process和web page 通信

    一.main process 和 web page 通信 electron框架主进程(Main Process)与嵌入的网页(web page,也就是renderer process)之间的通信 Ma ...

  9. hiveF 函数解析时间问题

    #!/bin/bashsource /etc/profileupdatetime=`date --date='0 days ago' +"%Y-%m-%d %H:%M:%S"`ec ...

  10. JavaScript基础学习(五)—其他引用类型

         JavaScript定义了两个内置对象: Global和Math. 一.Global对象 1.URI编码方法      Global对象的encodeURI()和encodeURICompo ...