【闲话】就算熬夜,也一定要先记录下这个题,我太开心了。。。。

【题意】给了一颗树,询问这个树里面每个点到树上其他点的最大距离,这个题是属于树形DP的,在前几周还讲到了这个题,(一切都是缘分),今天在整理树形dp又发现这个题,然后这里说了,这个题可以直接维护每个点到树直径端点的两个距离的最大值!

【分析】这么神奇吗?马上翻出树直径的板子,构思一下,20分钟写完debug的过程有点磁力呀,把max写成Min,看了好久,过掉样例,交上去TLE,原来是E【】写错了,应该是20004,写成2004,太不细心了。改掉过了这题了!

【开心】真的好开心,这个树形dp,竟然用看似很暴力的方法过掉了,以后可以吹一下这个题了!明早信号与系统,果断睡觉!!!

【AC代码】

//Tree_dp cpp
//just_sort 2016/4/17
#include <queue>
#include <stack>
#include <assert.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 10002;
const int maxm = 20004;
struct Edge{
   int v,w,next;
}E[maxm];
int n,tot;
int head[maxn],d1[maxn],d2[maxn];//d1保存点到树直径左端点的距离,d2保存点到树直径右端的距离
int x;//记录直径能到达的端点
void Init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}
void Add_Edge(int u,int v,int w)
{
    E[tot].v=v,E[tot].w=w;
    E[tot].next = head[u];
    head[u] = tot++;
    E[tot].v=u,E[tot].w=w;
    E[tot].next = head[v];
    head[v] = tot++;
}
void work()
{

}
void dfs(int u,int fa,int d[])//寻找直径,更新距离!!!
{
    int i,v;
    for(i=head[u]; ~i; i=E[i].next)
    {
        v = E[i].v;
        if(v!=fa)
        {
            d[v] = d[u] + E[i].w;
            if(d[x]<d[v]) x=v;
            dfs(v,u,d);
        }
    }
}

int main()
{
    int v,w;
    while(~scanf("%d",&n))
    {
        Init();
        for(int i=2; i<=n; i++)
        {
            scanf("%d%d",&v,&w);
            Add_Edge(i,v,w);
        }
        d1[1]=0,x=1,dfs(1,0,d1);
        d1[x]=0,    dfs(x,0,d1);
        d2[x]=0,    dfs(x,0,d2);
        for(int i=1; i<=n; i++)
        {
            printf("%d\n",max(d1[i],d2[i]));
        }
    }
    return 0;
}