HDU-2196-Computer(树形DP经典题)

Computer

Problem Description

A school bought the first computer some time ago(so this computer’s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

在这里插入图片描述

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.

Input

Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.

Output

For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).

Sample Input

5
1 1
2 1
3 1
1 1
 

Sample Output

3
2
3
4
4

解题思路:

题目有小坑,要多组输入。
给定一棵树,每条边有权值。
求每个点能到达的最远距离。
两遍DFS就可。
第一遍DFS求出每个点的每颗子树的最大长度。(只会用到前二长的两条)
第二遍DFS就可以求解答案了。传递两个参数。其中一个是上面父节点传下来的最长能到达的距离。然后往下DFS,往下DFS的时候考虑参数怎么选择,是选择上一层传下来的距离还是该点的前二长的距离。选最大值加上该点的权值往下传就行了。然后记录该点的答案值。也是上一层的值和子树的最大值取一个最大值就行了。

AC代码:

//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <map>
#include <queue>
#include <deque>
#define ios std::ios::sync_with_stdio(false)
#define int long long
using namespace std;
const int N = 3e5+10;
struct node{
    int val;
    vector<int> to;
    vector<pair<int,int> > dis;
}nodes[N];
int dp[N];

int dfs(int pos)
{
    int res = 0;
    for(int i = 0 ; i < nodes[pos].to.size() ; i ++)
    {
        int tmp = dfs(nodes[pos].to[i]);
        nodes[pos].dis.push_back(make_pair(nodes[pos].to[i],tmp));
        res = max(res,tmp);
    }
    return res + nodes[pos].val;
}

bool cmp(pair<int,int> x,pair<int,int> y)
{
    return x.second > y.second;
}

void dfs2(int pos,int sum)
{
    sort(nodes[pos].dis.begin(),nodes[pos].dis.end(),cmp);
    int dis1 = 0,dis2 = 0;
    int to1 = -1;
    if(nodes[pos].to.size() > 1) {dis1 = nodes[pos].dis[0].second; to1 = nodes[pos].dis[0].first; dis2 = nodes[pos].dis[1].second;}
    if(nodes[pos].to.size() > 0) {dis1 = nodes[pos].dis[0].second; to1 = nodes[pos].dis[0].first;}
    // cout<<pos<<" "<<sum<<" "<<dis1<<" "<<dis2<<endl;
    for(int i = 0 ; i < nodes[pos].to.size() ; i ++)
    {
        dfs2(nodes[pos].to[i],max(sum,(to1 == nodes[pos].to[i] ? dis2 : dis1))+nodes[nodes[pos].to[i]].val);
    }
    dp[pos] = max(sum,dis1);
}

signed  main()
{
    int n;
    while(cin>>n){
        for(int i = 1 ; i <= n ; i ++)
        {
            nodes[i].to.clear();
            nodes[i].dis.clear();
        }
        for(int i = 2 ; i <= n; i ++)
        {
            int x,y;
            cin>>x>>y;
            nodes[x].to.push_back(i);
            nodes[i].val = y;
        }
        nodes[1].val = 0;
        dfs(1);
        dfs2(1,0);
        for(int i =1 ; i <= n ; i ++)
            cout<<dp[i]<<endl;
    }
    return 0;
}

发布了104 篇原创文章 · 获赞 7 · 访问量 4061

猜你喜欢

转载自blog.csdn.net/qq_43461168/article/details/104210248