【题意】求树上每个点的最远距离是多少

对于<u,v>(有向),

dp[u][0]表示在u的子树下u的最远距离是多少

dp[u][1]表示在u的子树下(和dp[u][0]不是同一孩子)u的次远距离是多少

dp[u][2]表示通过u的父亲能走的最远距离是多少

第一次从下到上,对于<u,v>(有向),状态转移显然是 dp[u][0] = dp[v][0]+w[i];所以要先算出dp[v][0]才能知道dp[u][0]。故是从下往上。

第二次从上往下,其实就是再遍历一边图,把dp[v][2]算出来,显然:

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

对上述转移作一个简单解释:当dp[v][0]+w[i]==dp[u][0]时,说明这个点在u在u的子树下能走的最远距离包含了v点,那么dp[v][2]即v通过u的父亲能走的最远距离就是(u,v)这条边+max(dp[u][1],dp[u][2]). 如果不等,同理。

所以要算dp[v][2],要先算dp[u][0],所以从上往下。

最后的答案就是 max(dp[u][0],dp[u][2])

AC代码:

//树中某个节点到所有节点的最远距离
//author:zzy
#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
const int MAXN=10200;
#define eps 1e-10
#define inf 0x3f3f3f3f
#define ll long long
#define CL(a,b) memset(a,b,sizeof(a))
#define MAXN 100010
using namespace std;
struct edge
{  int a;int w;//权值
};
vector<edge> G[MAXN];
int tot;//总边数
void add_edge(int u,int v,int w)//添加从u->v,权值为w的边
{  struct edge E;E.a=u;E.w=w;  G[v].push_back(E);E.a=v;G[u].push_back(E);
}
int dist[MAXN][3];//dist[i][0,1,2]分别为正向最大距离,正向次大距离,反向最大距离
//int longest[MAXN];//下标是点,值是最远距离时对应点的位置
int dfs1(int u,int fa)//返回u的正向最大距离
{  if(dist[u][0]>=0) return dist[u][0];  dist[u][0]=dist[u][1]=dist[u][2]=0;  for(int i=0;i<G[u].size();i++)  {  int v= G[u][i].a;  if(v==fa)continue;  if(dist[u][0]<dfs1(v,u)+G[u][i].w)  {  dist[u][1] = max(dist[u][1] , dist[u][0]);  dist[u][0]=dfs1(v,u)+G[u][i].w;  }  else if( dist[u][1]< dfs1(v,u)+G[u][i].w )dist[u][1] = max(dist[u][1] , dfs1(v,u)+G[u][i].w);  }  return dist[u][0];
}
void dfs2(int u,int fa)
{  for(int i=0;i<G[u].size();i++)  {  int v = G[u][i].a;  if(v==fa)continue;  if(dist[u][0] == dist[v][0] + G[u][i].w) dist[v][2] = max(dist[u][2],dist[u][1])+G[u][i].w;  else dist[v][2] = max(dist[u][2],dist[u][0])+G[u][i].w;  dfs2(v,u);  }
}
int main()
{  int n;  while(scanf("%d",&n)==1&&n)  {  tot=0;  CL(dist,-1);  for(int i=1; i<=n; i++)   G[i].clear();for(int i=2; i<=n; i++)  {  int v,w;  scanf("%d%d",&v,&w);  add_edge(i,v,w);}  dfs1(1,-1);  dfs2(1,-1);  for(int i=1;i<=n;i++)  printf("%d\n",max(dist[i][0],dist[i][2]));  }  return 0;
}  

树形dp——树的最远距离 hdu2196相关推荐

  1. 树形DP+树状数组 HDU 5877 Weak Pair

    1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要 ...

  2. POJ - 4045 Power Station(树形dp/树的重心)

    题目链接:点击查看 题目大意:给出一个n个节点的树,我们需要选出一个节点,到其余任何节点的距离和最小 题目分析:这个题我的第一反应是用树的重心,先求出来符合条件的点,然后再跑一遍dfs求距离,最后输出 ...

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

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

  4. [BZOJ3197][Sdoi2013]assassin(树形DP+树同构+二分图最优匹配)

    关于树同构,有一个神奇的性质: 一棵树的重心只有 111 个或 2" role="presentation" style="position: relative ...

  5. 树形dp——树的重心(2) 代码调试理解

    和树的最大独立问题类似,先任选一个结点作为根节点,把无根树变成有根树,然后设d(i)表示以i为根的子树的结点的个数.不难发现d(i)=∑d(j)+1,j∈s(i).s(i)为i结点的所有儿子结点的编号 ...

  6. 树形dp ——树的重心

    1.只需要求出最大子树中节点数最小的数目即可 题意:有一个国王要把他的领土分给两个儿子,国王的领土是一棵树,N个结点,N-1条边把这些结点连起来,现在大小儿子要选择一个点作为他的首都,那么除首都分别是 ...

  7. 树形dp树的重心(D - Godfather POJ - 3107)

    题目链接:https://cn.vjudge.net/contest/277955#problem/D 题目大意:求树的重心(树的重心指的是树上的某一个点,删掉之后形成的多棵树中节点数最大值最小). ...

  8. 洛谷4895 BZOJ3162 独钓寒江雪 树形dp 树哈希

    题目链接 题意: 给定一棵无根树,求其中本质不同的独立集的个数.独立集就是一个集合中的点之间都没有边直接相连.n<=5e5n<=5e5n<=5e5,对1e9+71e9+71e9+7取 ...

  9. 【XSY2500】都城(树形dp)

    题面 Description Input Output Sample Input 4 1 4 2 4 3 4 Sample Output 2 2 2 3 HINT 题解 考虑到一个性质:任意两个相邻的 ...

最新文章

  1. 2021年AI关键趋势,AI芯片初创公司可能发生并购
  2. 5G — 3 大场景、8 大 KPI
  3. vim设置显示行号,vim跳转到文件头,文件尾
  4. db2 删除存储过程_数据库教程-SQL Server存储过程使用及异常处理
  5. 兄弟,就你这智商就别出轨了吧?
  6. java编码问题详解
  7. html5声称需要大写吗,html5中有没有规定字母标签是用大写还是小写?
  8. Error:java: Compilation failed: internal java compiler error
  9. MongoDB索引概念及使用详解
  10. centOS 自动锁屏 解决办法
  11. Linux_access the file or directory which start with -
  12. 工大瑞普虚拟思科实验室full(U7.3)环境配置方法
  13. ps怎么导入lut预设?Photoshop导入lut调色预设教程
  14. 关于微信各名词的英文翻译
  15. 韩顺平老师多用户即时通讯系统功能扩展:发送离线消息
  16. word如何转excel
  17. 怎么将svn服务器上的文件彻底删除,如何彻底删除SVN中的文件和文件夹(附恢复方法)...
  18. 神经网络模型文件后缀名,神经网络模型文件格式
  19. vue中使用电子签名
  20. JavaScript 中字符串截取 (+实现)

热门文章

  1. caffe这个c++工程的目录结构
  2. yanf4j引入了客户端非阻塞API
  3. angular-创建自定义的指令
  4. 如何开启PostGreSQL的远程访问端口?
  5. PHP中$_SERVER[QUERY_STRING]函数
  6. 求助:Event ID:10021日志错误的解决方法
  7. telegraf监控mysql数据库_部署Telegraf+Influxdb+Grafana 架构来监控 MySQL
  8. 如何识别和避免间谍软件
  9. 用Scrapy爬虫框架爬取食品论坛数据并存入数据库
  10. python pdf处理 图片_python PDF文件合并、图片处理