题目链接: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. Frame框架

    框架 frameset    框架集    如果使用框架集,当前页面不能有body    cols="300,*" :左右拆分,左边宽300,右边宽剩余    rows=" ...

  2. 在docker container中运行docker-compose

    为了保持宿主主机的环境干净,因此将docker-compose安装到一个基于centos7.3的容器之中,因为tianchao屏蔽了amazonaws,最后选择了通过pip方式来安装,这也是官方推荐的 ...

  3. 【Java 并发】详解 ThreadLocal

    前言 ThreadLocal 主要用来提供线程局部变量,也就是变量只对当前线程可见,本文主要记录一下对于 ThreadLocal 的理解.更多关于 Java 多线程的文章可以转到 这里. 线程局部变量 ...

  4. 【前端童鞋看过来!】给大家分享网盘里前端相关书籍,主要是和网络通信(HTTP/TCP/IP)及javascript相关的

    百度云链接:https://pan.baidu.com/s/1kUPdf5H(无密码) 截图: <HTTP权威指南> [豆瓣书评]:此书第一部分是HTTP的概略,如果你没有时间,通读第一部 ...

  5. placeholder的字体样式改变,滚动条的颜色改变,ios日期兼容

    placeholder:::-webkit-input-placeholder { color: rgba(153, 153, 153, 0.541);font-size:12px;}:-moz-pl ...

  6. 实现标签的添加与删除(tags)

    在项目中会遇到,标签(tags)的添加与去除的需求 demo:我们有 tags   '专利','商标','版权','域名' demand:在发布内容的时候,要求可以添加tag,(实现tag的增加与删除 ...

  7. Oracle常见错误集锦

    1.ORA-12560:TNS:协议适配器错误 OracleService<SID>服务没有启动 2. ORA-12541:TNS:无监听程序 Oracle<ORACLE_HOME& ...

  8. C#重的数组、集合(ArrayList)、泛型集合(list<T>)三者比较及扩展延伸……

    本来我只想总结下数组.集合(ArrayList).泛型集合(list<T>)三者的比较的,可以一写下来要扩展的知识点有点多了,只能写一个小的知识点列表了如下: 1.数组.集合(ArrayL ...

  9. JavaWeb总结(三)—JSP

    一.JSP简介 1.基本认识 (1)JSP页面是由HTML语句和嵌套在其中的Java代码组成的一个普通文本文件,JSP 页面的文件扩展名必须为.jsp. (2)在JSP页面中编写的Java代码需要嵌套 ...

  10. 跟着刚哥梳理java知识点——HelloWorld和常见问题(一)

    1.按照国际惯例,写一段输出HelloWorld的java语句: public class HelloWorld { //这是main方法,程序的主入口 public static void main ...