给出一棵树,边有权值,求出离每一个节点最远的点的距离

树形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=+;
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][]; void init()
{
memset(head,-,sizeof head);
tot=;
memset(dp,,sizeof dp);
memset(son,-,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[]=;
for(int i=;i<=n;i++)
{
int u;
scanf("%d %d",&u,&cost[i]);
addedge(u,i);
}
solve(n);
}
return ;
} void solve(int n)
{
dfs1(,-);
dfs2(,-);
dp[][]=;
dfs3(,-); for(int i=;i<=n;i++)
{
printf("%d\n",max(dp[i][],dp[i][]));
}
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][]+cost[v]>dp[u][])
{
dp[u][]=dp[v][]+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][]+cost[v]>dp[u][])
dp[u][]=dp[v][]+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][]=max(dp[u][],dp[u][])+cost[v];
}
else
{
dp[v][]=max(dp[u][],dp[u][])+cost[v];
}
dfs3(v,u);
}
}

最新文章

  1. [转]ASP.NET Core 之 Identity 入门(三)
  2. python 01
  3. Hadoop入门进阶课程3--Hadoop2.X64位环境搭建
  4. NeHe OpenGL教程 第十课:3D世界
  5. C#构造函数使用
  6. c# Parallel并行运算
  7. android获取存储卡使用情况
  8. Sping3.0版本+Quartz完成定时任务
  9. C#通过socket判断FTP服务器是否通畅并判断用户名密码是否正确
  10. SQL更新语句,Error Code: 1175. You are using safe update(在进行视图更新的时候遇到)
  11. C#调用java方法踩坑记
  12. PHP——emjoin表情存入数据库
  13. cf478d 线性dp好题
  14. JS自学笔记02
  15. SiteCore Experience Analytics-路径分析地图
  16. rt.jar sun package
  17. 使用Js控制ReactRouter路由
  18. OneZero第三周第二次站立会议(2016.4.5)
  19. JavaEE笔记(十四)
  20. prometheus and collectd and docker

热门文章

  1. poj1128 拓扑序(DFS)
  2. C++@冒号(:)和双冒号(::)的用法
  3. 关于Lua程序设计{读书笔记}
  4. eclipse adt 项目依赖,使用git上的项目
  5. flashbuilder发布release版本
  6. __LINE__ __DATE__ __FILE__ __TIME__ 等宏定义解释
  7. oracle_dblink配置
  8. asp.net系统过滤器、自定义过滤器
  9. javascript保留两位小数
  10. HTML,XML中的转义字符