题目链接:点击查看

题目大意:给定n个点以及n-1条边,保证可以组成一棵树,问每个点所能到达的最远距离

题目分析:首先这是一颗无向图所组成的树,经过分析,我们可以得到任何一个点,对于它所能到达的最远距离取决于两个条件,一个是该点向下可以到达的最远距离,或者是该点向上可以到达的最远距离,求该点向下的距离好求,可以利用树形dp的一般形式,回溯法,直接自底向上地往上求,不仅需要维护一个最大值,还需要维护一个次大值,接下来会用到,然后就是怎么求向上可以达到的距离了,我们可以在写一个dfs,刚才那个是自底向上维护,那么新的dfs就变成自顶向下维护就好了,其实本质上就是交换了一下转移方程和递归入口的顺序。

那么接下来在分析一下转移方程该怎么写,刚才我们提到了一共需要维护三个值,即向下的最大值,向下的次大值和向上的最大值,故我们需要用三个数组来维护,我们就用dp[N][3]来维护,第一维分别表示每个点,第二维的0,1,2分别表示以上三个值。

关于最大值和次大值,只需要遵循

  1. 更新最大值前先更新次大值
  2. 更新不了最大值时检查是否可以更新次大值

这样就可以直接自底向上转移了,还剩一个向上的最大值,这个我们该怎么想呢

我先将转移方程放上然后在来解释:

dp[v][2]=max(dp[v][0]+w==dp[u][0]?dp[u][1]:dp[u][0],dp[u][2])+w;

其中v表示为u的儿子,w表示为u和v之间的权值

既然是自顶向下转移,那么转移的方向就是u->v来转移,dp[u][2]可以当做已知条件来用,我们可以直接用这个值加上u和v之间的权值w来更新dp[v][2],这样确实是其中的一种情况,但却不一定是最优解,所以我们需要经过比较选择出最优解来更新dp[v][2]才行,那么还有哪些途径可以更新它呢?我们假设当前的u为根节点,那么既然v位于u的子树中,我们需要判断v是否位于u向下最大值的子树中,如果是的话,那么经过v点向上,我们可以经过根节点u当做中转点,到达u点的另一个次大值的子树中,这样可以保证了距离最大,如果v不在u的向下最大值的子树中,那么必定可以经过u到达最大值的子树中,这样通过比较这三种情况来确定了更新dp[v][2]的状态。

最后输出的结果便是从dp[i][0]和dp[i][2]中选择较大的一个输出了。

上代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
#include<cmath>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e4+100;struct Node
{int to,w;Node(int TO,int W){to=TO;w=W;}
};vector<Node>node[N];int dp[N][3];//0:向下最大值,1:向下次大值,2:向上最大值void dfs_down(int u,int fa)
{int mmax=0;//最大值int mx=0;//次大值for(int i=0;i<node[u].size();i++){int v=node[u][i].to;int w=node[u][i].w;if(v==fa)continue;dfs_down(v,u);int temp=dp[v][0]+w;if(temp>=mmax){mx=mmax;mmax=temp;}else if(temp>mx){mx=temp;}}dp[u][0]=mmax;dp[u][1]=mx;
}void dfs_up(int u,int fa)
{for(int i=0;i<node[u].size();i++){int v=node[u][i].to;int w=node[u][i].w;if(v==fa)continue;dp[v][2]=max(dp[v][0]+w==dp[u][0]?dp[u][1]:dp[u][0],dp[u][2])+w;dfs_up(v,u);}
}int main()
{
//  freopen("input.txt","r",stdin);int n;while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)node[i].clear();for(int i=2;i<=n;i++){int w,u;scanf("%d%d",&u,&w);node[u].push_back(Node(i,w));node[i].push_back(Node(u,w));}memset(dp,0,sizeof(dp));dfs_down(1,-1);dfs_up(1,-1);for(int i=1;i<=n;i++)cout<<max(dp[i][0],dp[i][2])<<endl;}return 0;
}

HDU - 2196 Computer(树形dp)相关推荐

  1. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  2. HDU - 2196(树形DP)

    题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...

  3. hdu 2196(经典树形dp)

    题意:给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离 解题思路:这道题网上说是经典的树形dp,不过确实很巧妙.两次dfs应该是比较好想到的,因为某节点最大的距离要么就是一直走到叶子节点, ...

  4. HDU Starship Troopers (树形DP)

    Starship Troopers Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) ...

  5. HDU 5148 Cities (树形DP)*

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5148 #include<bits/stdc++.h> using namespace st ...

  6. HDU - 4705 Y(树形dp)

    题目链接:点击查看 题目大意:给出一棵树,求三个点不在一条线上的个数 题目分析:正难取反,正着求不管是暴力还是有点技巧都是实现不了的,我们可以求出来三个点在一条直线上的方案数,然后用总的排列组合的方案 ...

  7. HDU - 5242 Game(树形dp+树链剖分/树上贪心+思维)

    题目链接:点击查看 题目大意:给出一棵包含n个节点的树,每个节点都有一个权值,整棵树的根是点1,问从点1开始向下一直走到叶子节点,可以走k次,怎么样走权值和最大,每个节点被走过一次后权值会变为0 题目 ...

  8. Problem F. Grab The Tree HDU - 6324(树形dp+博弈)

    Little Q and Little T are playing a game on a tree. There are nn vertices on the tree, labeled by 1, ...

  9. HDU 4616 Game 树形DP

    Problem Description Nowadays, there are more and more challenge game on TV such as 'Girls, Rush Ahea ...

最新文章

  1. 在hadoop上运行python_hadoop上运行python程序
  2. IT圈,他的牙如此不同
  3. synchronized关键字实现原理
  4. 第三次学JAVA再学不好就吃翔(part108)--带缓冲的字符流
  5. windows相关知识点分析
  6. 中班机器人上课视频_家委会:出班费买智能扫地机器人,不用家长搞卫生了,莫名其妙...
  7. OpenCV学习笔记(三):图像对比度、亮度调整源码
  8. 为什么有些女孩在发现渣男的真面目以后,还喜欢他们?
  9. 【计算机组成原理】指令格式
  10. asp.net用url重写URLReWriter实现任意二级域名(续)
  11. 基于JAVA+SpringMVC+Mybatis+MYSQL的教学管理平台
  12. remmima 不能保存_不再使用RememBear密码管理器忘记密码
  13. 用gambit学博弈论--完全信息动态博弈-博弈扩展式、博弈树(二)
  14. 《鹰猎长空》讲述戏曲与电影的渊源
  15. (二)PUN 2基本教程
  16. 阿里云盘PC端内测版可以下载安装了 还送你800G扩容福利码!
  17. Qt开发之QLineEdit简单介绍
  18. multimap的实际用途
  19. 猪哥学习群直播第一期:人工智能在银行电信企业中的应用
  20. 【北京.5月28日】第六届 Mobile Dev Day – WP7优秀应用经验分享日

热门文章

  1. Docker常用操作
  2. 字符串转换成ascii码
  3. Hive的基本操作-自定义函数
  4. Hive的基本操作-创建内部表
  5. RocketMQ的存储之消息的同步、异步刷盘
  6. Servlet_执行原理
  7. Zuul:Pre和Post过滤器(下)
  8. Zuul指定path+serviceid
  9. SpringBoot_数据访问-整合MyBatis(二)-配置版MyBatis
  10. 并行算法设计与性能优化_CME 323: 分布式算法与优化(1)