HDU 2196 Computer 树形DP 经典题
2015-08-20 01:01
537 查看
给出一棵树,边有权值,求出离每一个节点最远的点的距离
树形DP,经典题
本来这道题是无根树,可以随意选择root,
但是根据输入数据的方式,选择root=1明显可以方便很多。
我们先把边权转化为点权,放在数组cost中
令tree(i)表示以节点i为根的子树
对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面
令:
dp[i][1] : 在子树tree(i)中,离i最远的距离
dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)
dp[i][0] : 在树tree(root)-tree(i)中,离i最远的距离
son[i] : 在子树tree(i)中,离i最远的点是在tree(son[i])中,即最远路径经过节点son[i]
则对于每一个i,离i最远的距离=max(dp[i][0],dp[i][1])
流程:
0.链式前向星建树
1.dfs1,确定dp[i][1]
2.dfs2,确定dp[i][2]
dfs1和dfs2都很简单
3.dfs3,递推确定dp[i][0]
View Code
树形DP,经典题
本来这道题是无根树,可以随意选择root,
但是根据输入数据的方式,选择root=1明显可以方便很多。
我们先把边权转化为点权,放在数组cost中
令tree(i)表示以节点i为根的子树
对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面
令:
dp[i][1] : 在子树tree(i)中,离i最远的距离
dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)
dp[i][0] : 在树tree(root)-tree(i)中,离i最远的距离
son[i] : 在子树tree(i)中,离i最远的点是在tree(son[i])中,即最远路径经过节点son[i]
则对于每一个i,离i最远的距离=max(dp[i][0],dp[i][1])
流程:
0.链式前向星建树
1.dfs1,确定dp[i][1]
2.dfs2,确定dp[i][2]
dfs1和dfs2都很简单
3.dfs3,递推确定dp[i][0]
#include<cstdio> #include<cstring> using namespace std; const int maxn=10000+5; const int inf=0x3f3f3f3f; inline int max(int a,int b) { return a>b?a:b; } struct Edge { int to,next; }; Edge edge[maxn]; int head[maxn]; int tot; int cost[maxn]; int son[maxn]; int dp[maxn][3]; void init() { memset(head,-1,sizeof head); tot=0; memset(dp,0,sizeof dp); memset(son,-1,sizeof son); } void addedge(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void solve(int n); void dfs1(int u,int pre); void dfs2(int u,int pre); void dfs3(int u,int pre); int main() { int n; while(~scanf("%d",&n)) { init(); cost[1]=0; for(int i=2;i<=n;i++) { int u; scanf("%d %d",&u,&cost[i]); addedge(u,i); } solve(n); } return 0; } void solve(int n) { dfs1(1,-1); dfs2(1,-1); dp[1][0]=0; dfs3(1,-1); for(int i=1;i<=n;i++) { printf("%d\n",max(dp[i][0],dp[i][1])); } return ; } void dfs1(int u,int pre) { for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; dfs1(v,u); if(dp[v][1]+cost[v]>dp[u][1]) { dp[u][1]=dp[v][1]+cost[v]; son[u]=v; } } } void dfs2(int u,int pre) { for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; dfs2(v,u); if(v==son[u]) continue; if(dp[v][1]+cost[v]>dp[u][2]) dp[u][2]=dp[v][1]+cost[v]; } } void dfs3(int u,int pre) { for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(v==son[u]) { dp[v][0]=max(dp[u][0],dp[u][2])+cost[v]; } else { dp[v][0]=max(dp[u][0],dp[u][1])+cost[v]; } dfs3(v,u); } }
View Code
相关文章推荐
- Scala 深入浅出实战经典 第11讲:Scala中的apply实战详解
- [LeetCode] Find Peak Element
- Java多线程实现同步——wait()和notify()实现
- 一次mysql占用cpu高的处理过程
- OC_调用系统短信_邮件_电话
- Codeforces Round #316 (Div. 2)
- 关情纸尾-----UIkit基础-UIScrollView
- 如何让CRectTracker的m_rect不超出一定的范围,比如screen或者某个document的范围
- 图解classloader加载class的流程及自定义ClassLoader
- 黑马程序员——Java基础网络编程
- Gym 100490E-E - Environment Problems- 伸展树/平衡树/离散化点
- 利用Fragment编写简易新闻界面,布局同时适应Android手机和平板电脑
- 关于UITabBarController (非自定义)
- Ubuntu14.04下搭建LAMP环境
- HDOJ 3790 最短路径问题(dijkstra算法)
- 关于类文件从加载到运行的过程中内存的示意图
- C语言主函数返回值问题:return type of 'main' is not 'int' [-Wmain]
- UrlRewriteFilter 简介
- HDU 1372(BFS)
- ggplot2——柱状图