HDU-2196-コンピュータ(DP木クラシックのタイトル)

コンピューター

問題の説明

学校はいくつかの時間前に最初のコンピュータを買った(このコンピュータのIDが1であるので)。近年中に学校はN-1新しいコンピュータを買いました。それぞれの新しいコンピュータは定住以前の1に接続されていました。学校の管理者は、ネットの遅い機能について心配していると、i番目のコンピュータは(最も遠いコンピュータにケーブルの長さ、すなわち)に信号を送信する必要のある最大距離のSiを知りたいです。あなたは、この情報を提供する必要があります。

ここに画像を挿入説明

ヒント:例えば、入力は、このグラフに対応しています。そして、グラフから、あなたはS3ようS2 = 2.コンピュータ5は、3から最も遠いものですので、S1 = 3.コンピュータ4と5は、2から最も遠いものですので、コンピュータ4は、1から最も遠い1であることがわかります= 3.私たちもGET S4 = 4、S5 = 4。

入力

入力ファイルは、複数のテストcases.Inに(N-1)に続く最初の行の自然数N(N <= 10000)、コンピュータの説明を行があり、それぞれの場合を含んでいます。コンピュータの数、i番目のコンピュータが接続され、ケーブルの長さは、接続のために使用されている - 私は番目のラインは、二つの自然数を含んでいます。ケーブルの全長は10 ^ 9を超えません。入力の行の数字は、スペースで区切られています。

出力

各ケースの出力Nラインのため。i番目の行は、i番目のコンピュータ(1 <= I <= N)のための数のSiを含有しなければなりません。

サンプル入力

5
1 1
2 1
3 1
1 1
 

サンプル出力

3
2
3
4
4

問題解決のアイデア:

入力の複数のセットの対象がありピット。
ツリー、各値の右側に与えられました。
各要求は最も遠い地点に到達することができます。
DFSは二回することができます。
DFSは、最初のすべての単一のサブツリーは、各点の最大長を決定される渡します。(最初の2つの長い2を使用)
第二DFSが答えを解決することができる渡します。2つのパラメータを渡します。ここで受け継が上記親ノードに到達することが最長です。その後DFS、DFSダウンパラメータを選択する方法を検討するダウンタイム、選択層の前に2人の長い距離は、その点から受け継がれています。プラス右はラインの下の点広がりの最大値を選択します。そして、この時点の答えを記録します。そしてまた、レベル値は、ライン上の最大値のサブツリーの最大値をとります。

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