Hdu 2196 Computer

题意:给你一棵树,让你求出每个点离树上最远的距离.

...不会做,想了半天查了题解。

对于每一个点最远距离,要么是往下走,要么是从父节点下来的。

dp[u][0]表示跑儿子路的最大值,dp[u][1]表示跑儿子路的次大值.为什么要记录次大值呢。

dp[u][2]表示往父亲那里跑的最大值.

dp[v][2]照常理来说应该是等于max(dp[u][0],dp[u][2])+w[u][v].但是dp[u][0]有可能是从dp[v][0]那里得到的,如下图那种情况dp[u][0]就是跑向v的那里.这种情况下就要用max(dp[u][1],dp[u][2])+w[u][v];

#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#include <set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
#define X first
#define Y second
#define mp(a,b) make_pair(a,b)
#define pb push_back
#define sd(x) scanf("%d",&(x))
#define Pi acos(-1.0)
#define sf(x) scanf("%lf",&(x))
#define ss(x) scanf("%s",(x))
#define maxn 10005
const int inf=0x3f3f3f3f;
const ll mod=1000000007;
struct node
{
    int v,w,next;
}E[maxn];
int top;
int head[maxn];
void add(int u,int v,int w)
{
    E[top].v=v;
    E[top].w=w;
    E[top].next=head[u];
    head[u]=top++;
}
int dp[maxn][3];
void dfs(int u)
{
    int mm=0,sm=0,v,pa;
    for(int i=head[u];i!=-1;i=E[i].next)
    {
        v=E[i].v;
        dfs(v);
        pa=dp[v][0]+E[i].w;
        if(pa>=mm)
        {
            sm=mm;
            mm=pa;
        }
        else if(pa>=sm)
            sm=pa;
    }
    dp[u][0]=mm;
    dp[u][1]=sm;
}
void dfs2(int u)
{
    int v;
    for(int i=head[u];i!=-1;i=E[i].next)
    {
        v=E[i].v;
        dp[v][2]=max(dp[u][2],dp[v][0]+E[i].w==dp[u][0]?dp[u][1]:dp[u][0])+E[i].w;
        dfs2(v);
    }
}
int main()
{
#ifdef local
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
    int _time=clock();
#endif
    int n;
    while(cin>>n){
            top=0;
    memset(head,-1,sizeof head);
    for(int v=2;v<=n;v++)
    {
        int u,w;
        scanf("%d%d",&u,&w);
        add(u,v,w);
    }
    dfs(1);
    dp[1][2]=0;
    dfs2(1);
    for(int i=1;i<=n;i++)
    {
        printf("%d
",max(dp[i][0],dp[i][2]));
    }
    }
#ifdef local
    printf("time: %d
",int(clock()-_time));
#endif
}
View Code
原文地址:https://www.cnblogs.com/scau-zk/p/5668001.html