HDU-2196 Computer

题意:

就问你每个节点到以这个点为根的子树的叶子节点的最远距离。

链接: http://acm.hdu.edu.cn/search.php?action=listproblem

思路:

我们设DP[i][0]表示以i节点为根节点的子树中的最远距离,

DP[i][1]表示以i节点为根节点的子树中的次远距离,

DP[i][2]表示通过i的父亲节点能走到的最远距离。

答案即为max(DP[i][2],DP[i][0]),通过两遍dfs解决

代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+ 5;
const int INF = 1e16;
typedef long long ll;
int a[MAXN],dp[MAXN][3];
int head[MAXN],tot;
struct node
{
    int to,nxt,val;
} e[MAXN<<2];
void add(int x,int y,int z)
{
    e[tot].to=y;
    e[tot].val=z;
    e[tot].nxt=head[x];
    head[x]=tot++;
}
void dfs1(int u,int fa)    //由下至上更新
{
    for(int i=head[u]; ~i; i=e[i].nxt)
    {
        int v=e[i].to;
        dfs1(v,u);
        int temp=dp[v][0]+e[i].val;
        if(temp>=dp[u][0])
        {
            dp[u][1]=dp[u][0];
            dp[u][0]=temp;
        }
        else
            dp[u][1]=max(dp[u][1],temp);
    }
}
void dfs2(int u,int fa)       //由上至下更新
{
    for(int i=head[u]; ~i; i=e[i].nxt)
    {
        int v=e[i].to;
        if(dp[v][0]+e[i].val==dp[u][0])
            dp[v][2]=max(dp[u][2],dp[u][1])+e[i].val;
        else
            dp[v][2]=max(dp[u][0],dp[u][2])+e[i].val;
        dfs2(v,u);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    while(cin>>n)
    {
        memset(head,-1,sizeof(head));tot=0;
        memset(dp,0,sizeof(dp));
        for(int i=2; i<=n; i++)
        {
            int x,z;
            cin>>x>>z;
            add(x,i,z);
        }
        dfs1(1,-1);
        dfs2(1,-1);
        for(int i=1; i<=n; i++)
            cout<<max(dp[i][0],dp[i][2])<<endl;
        //cout<<max(dp[n][0],dp[n][2])<<endl;
    }

}

 

posted @ 2020-03-14 14:21  grass_lin  阅读(109)  评论(0编辑  收藏  举报