HDU 2196 Computer 树形DP 经典题
2024-10-13 14:14:48
给出一棵树,边有权值,求出离每一个节点最远的点的距离
树形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);
}
}
最新文章
- [转]ASP.NET Core 之 Identity 入门(三)
- python 01
- Hadoop入门进阶课程3--Hadoop2.X64位环境搭建
- NeHe OpenGL教程 第十课:3D世界
- C#构造函数使用
- c# Parallel并行运算
- android获取存储卡使用情况
- Sping3.0版本+Quartz完成定时任务
- C#通过socket判断FTP服务器是否通畅并判断用户名密码是否正确
- SQL更新语句,Error Code: 1175. You are using safe update(在进行视图更新的时候遇到)
- C#调用java方法踩坑记
- PHP——emjoin表情存入数据库
- cf478d 线性dp好题
- JS自学笔记02
- SiteCore Experience Analytics-路径分析地图
- rt.jar sun package
- 使用Js控制ReactRouter路由
- OneZero第三周第二次站立会议(2016.4.5)
- JavaEE笔记(十四)
- prometheus and collectd and docker
热门文章
- poj1128 拓扑序(DFS)
- C++@冒号(:)和双冒号(::)的用法
- 关于Lua程序设计{读书笔记}
- eclipse adt 项目依赖,使用git上的项目
- flashbuilder发布release版本
- __LINE__ __DATE__ __FILE__ __TIME__ 等宏定义解释
- oracle_dblink配置
- asp.net系统过滤器、自定义过滤器
- javascript保留两位小数
- HTML,XML中的转义字符