HDU 2196
来源:互联网 发布:sql 别名的使用 编辑:程序博客网 时间:2024/05/27 06:52
//树形DP,求树的最大直径。。。。
#include<stdio.h>
#include<string.h>#include<vector>
using namespace std;
#define Max(x,y) (x>y?x:y)
#define max 10000+5
vector<int> next[max];//存图
int n,cost[max],dp[max],sec[max],up[max],f[max];
//dp[i] 结点i在其子树上的最大直径
//sec[i]结点i在其子树上的次最大直径
//up[i] 结点i通过其父结点可获得的最大直径
//f[i] 结点i在其子树上获得最大直径所通过的子结点
void init(){
for(int i=0;i<=n;i++){
next[i].clear();
}
memset(sec,0,sizeof(sec));
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
memset(up,0,sizeof(up));
memset(cost,0,sizeof(cost));
}
int dfs(int u){
int pre;//记录在子树上获得最大直径所通过的子结点
int& res=dp[u];
for(int i=0;i<next[u].size();i++){
int v=next[u][i];
int temp=dfs(v)+cost[v];
if(res<temp){ //更新最大直径
sec[u]=res;
res=temp; pre=v;
}
else if(temp>sec[u]){//更新次最大直径
sec[u]=temp;
}
}
f[u]=pre;
return res;
}
void DP(int u){
for(int i=0;i<next[u].size();i++){
int v=next[u][i];
if(f[u]==v){ //如果结点u通过其子结点v得到最大直径
up[v]=Max(up[u],sec[u])+cost[v];
}
else{
up[v]=Max(up[u],dp[u])+cost[v];
}
DP(v);
}
}
int main(){
while(~scanf("%d",&n)){
init();
for(int i=2;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
next[a].push_back(i);
cost[i]=b;
}
dfs(1); //计算每个结点到其子树上叶结点最大距离
DP(1); //更新最大距离
for(int i=1;i<=n;i++){
printf("%d\n",Max(dp[i],up[i]));//取向下和向上的最大值
}
}
}
- hdu 2196
- HDU 2196
- HDU 2196
- HDU 2196
- HDU 2196
- hdu 2196
- HDU 2196
- HDU 2196
- hdu 2196
- HDU 2196 Computer
- hdu 2196 Computer
- hdu 2196 Computer
- hdu 2196 树型DP
- HDU 2196 树形dp
- hdu 2196 dfs
- HDU 2196 树状DP
- HDU 2196 树形dp
- HDU 2196 Computer
- 网页控件OCX
- Preference 隐藏
- node.js addon osg binding 2
- 社保问题:广东省内社保转移接续问题
- DrawText函数的讲解
- HDU 2196
- C语言笔记(3)
- Android SDK更新过程中出现connection refused 或者 error问题(Windows 和Ubuntu安装过程中的问题)
- C语言笔记(typedef, 缓冲)
- poj 2063完全背包
- 基于Linux的v4l2视频架构驱动的应用 对视频采集和工作过程有帮助
- a的n次方
- Error---Uri can't be resolved to a type
- 深入了解epoll 函数