HDU 2196 Computer 经典树形DP

一开始看错题了,后来发现原来是在一颗带权的树上面求出距离每一个点的最长距离,做两次dfs就好,具体的看注释?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
 
using namespace std;
 
typedef long long LL;
const int maxn = 10000 + 5;
int ch[maxn],nxt[maxn],v[maxn],w[maxn];
int mdep[maxn],sdep[maxn],f[maxn],mfrom[maxn];
int ecnt,n;
 
inline void addedge(int uu,int vv,int ww) {
    v[ecnt] = vv; w[ecnt] = ww; nxt[ecnt] = ch[uu]; ch[uu] = ecnt++;
}
 
//dfs求解从子节点过来的最大值和次大值
int dfs(int now) {
    mdep[now] = sdep[now] = 0;
    if(ch[now] == -1) return 0;
    for(int i = ch[now];~i;i = nxt[i]) {
        int ret = dfs(v[i]) + w[i];
        if(ret > mdep[now]) {
            sdep[now] = mdep[now]; mdep[now] = ret;
            mfrom[now] = v[i];
        }
        else if(ret > sdep[now]) sdep[now] = ret;
    }
    return mdep[now];
}
 
//dfs1求出答案
void dfs1(int now) {
    //如果当前节点是叶子节点,最大值必定是从父亲节点更新过来的
    if(ch[now] == -1) return;
    //否则往下更新
    for(int i = ch[now];~i;i = nxt[i]) {
        if(mfrom[now] == v[i]) {
            //如果当前儿子这边有最大深度
            f[v[i]] = max(f[now],sdep[now]) + w[i];
        }
        else f[v[i]] = max(f[now],mdep[now]) + w[i];
        dfs1(v[i]);
    }
    //最大距离来自儿子
    f[now] = max(f[now],mdep[now]);
}
 
int main() {
    while(scanf("%d",&n) != EOF) {
        memset(ch,-1,sizeof(ch));
        memset(f,0,sizeof(f));
        memset(mfrom,-1,sizeof(mfrom));
        ecnt = 0;
        for(int i = 2;i <= n;i++) {
            int a,b; scanf("%d%d",&a,&b);
            addedge(a,i,b);
        }
        dfs(1);
        dfs1(1);
        for(int i = 1;i <= n;i++) printf("%d\n",f[i]);
    }
    return 0;
}

  

posted @   acm_roll  阅读(135)  评论(0编辑  收藏  举报
编辑推荐:
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
阅读排行:
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 2025成都.NET开发者Connect圆满结束
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 用一种新的分类方法梳理设计模式的脉络
点击右上角即可分享
微信分享提示