[树形DP]HDU 2196-Computer
Posted alice593
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[树形DP]HDU 2196-Computer相关的知识,希望对你有一定的参考价值。
题目大意
求树中每个点到任意点的最长距离
思路
该距离有两种,一种是经过父亲节点的,一种是子树里的
定义dp[x][0/1]表示x到叶子节点的最大距离和次大距离
dp[x][2]表示经过父亲节点的最长路径
dp[x][2]可以是先走到父亲节点,再走到父亲的其他儿子,也可能是走到父亲节点再走到父亲的父亲
此时若父亲的最远叶子节点经过该点,就用次大值更新,否则用最大值更新
#include<cstdio>
#include<cstring>
#include<iostream>
#define max(a,b) ((a)>(b)?(a):(b))
typedef long long ll;
const int maxn=10000+5;
inline int Read(){
int x=0;char c=getchar();
while(‘0‘>c||c>‘9‘)c=getchar();
while(‘0‘<=c&&c<=‘9‘)x=(x<<1)+(x<<3)+c-48,c=getchar();
return x;
}
struct Edge{
int to,nxt,data;
}e[maxn<<1];
int n,head[maxn],cnt,dp[maxn][3];
inline void Insert(int x,int y,int z){
e[++cnt].to=y;e[cnt].data=z;
e[cnt].nxt=head[x];head[x]=cnt;
}
#define y e[i].to
void Dfs1(int x){
dp[x][0]=dp[x][1]=dp[x][2]=0;
for(int i=head[x];i;i=e[i].nxt){
Dfs1(y);
if(dp[y][0]+e[i].data>dp[x][0]){
dp[x][1]=dp[x][0];
dp[x][0]=dp[y][0]+e[i].data;//dp[x][0]表示x到子树内叶节点的最长距离
}
else dp[x][1]=max(dp[x][1],dp[y][0]+e[i].data);//dp[x][1]表示次长距离
}
}
void Dfs2(int x){
for(int i=head[x];i;i=e[i].nxt){
if(dp[x][0]==dp[y][0]+e[i].data)
dp[y][2]=max(dp[x][1],dp[x][2])+e[i].data;
else dp[y][2]=max(dp[x][0],dp[x][2])+e[i].data;
Dfs2(y);
}//dp[x][2]表示经过父节点取得的最长路径,此时可以到父亲节点再到父亲的其他儿子,也可以从父亲到父亲的父亲
//如果父节点到叶子节点的最大值经过y,那么就用次大值更新,否则就用最大值
}
#undef y
int main(){
int x,y;
while(scanf("%d",&n)!=EOF){
cnt=0;
memset(head,0,sizeof(head));
for(int i=2;i<=n;++i)x=Read(),y=Read(),Insert(x,i,y);
Dfs1(1);Dfs2(1);
for(int i=1;i<=n;++i)printf("%d
",max(dp[i][0],dp[i][2]));
}
return 0;
}
以上是关于[树形DP]HDU 2196-Computer的主要内容,如果未能解决你的问题,请参考以下文章