您的位置:首页 > 其它

[HDU 2196] Computer 树形dp

2015-08-06 20:15 417 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2196

题意:开始输入 n ,表示有 n 个顶点,然后输入 n - 1 行,第 i 行两个数 x, y 表示 i, x有一条边, 路径长度为 y ,求每个点和离这个点距离最远的点之间的距离。

思路:用个数组dp[i][2]记录一下每个节点 i 的最远距离和次远距离。首先 dfs 一次,把每个点除父结点以外的的最远距离和次远距离求出来,然后再 dfs 一次把父结点方向的距离也加入到最远和次远距离中。

[code]#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long loli;

struct node{
    int to;
    int val;
    node(int x = 0, int y = 0){
        to = x;
        val = y;
    }
};

int n;
loli dp[10010][2];
vector<node> tr[10010];

loli Dfs_1(int rt, int pre) //求每个点除父结点方向以外的最远距离和次远距离
{
    int len = tr[rt].size();
    dp[rt][0] = dp[rt][1] = 0;
    for(int i = 0; i < len; i++){
        int son = tr[rt][i].to;
        if(son == pre)
            continue;
        loli flag = Dfs_1(son, rt) + tr[rt][i].val;
        if(flag > dp[rt][0]){ //更新最远距离
            dp[rt][1] = dp[rt][0]; //最远变次远
            dp[rt][0] = flag;
        }
        else if(flag > dp[rt][1]){ //更新次远距离
            dp[rt][1] = flag;
        }
    }
    return dp[rt][0];
}

int Dfs_2(int rt, int pre, loli sum) //sum 是父结点方向的最远距离
{
    int len = tr[rt].size();
    if(sum > dp[rt][0]){ //更新最远距离
        dp[rt][1] = dp[rt][0]; //最远变次远
        dp[rt][0] = sum;
    }
    else if(sum > dp[rt][1]){ //更新次远距离
        dp[rt][1] = sum;
    }
    for(int i = 0; i < len; i++){
        int son = tr[rt][i].to;
        if(son == pre)
            continue;
        if(dp[son][0] + tr[rt][i].val == dp[rt][0]) //当前方向是最远距离
            Dfs_2(son, rt, dp[rt][1] + tr[rt][i].val); //传递次远距离
        else
            Dfs_2(son, rt, dp[rt][0] + tr[rt][i].val);  //不是最远距离方向
    }
}

int main()
{
    while(cin>>n){
        int x, y;
        for(int i = 0; i <= n; i++){
            tr[i].clear();
        }
        for(int i = 2; i <= n; i++){
            cin>>x>>y;
            tr[i].push_back(node(x, y));
            tr[x].push_back(node(i, y));
        }
        Dfs_1(1, -1);
        Dfs_2(1, -1, 0);
        for(int i = 1; i <= n; i++){
            cout<<dp[i][0]<<endl;
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: