【闲话】就算熬夜,也一定要先记录下这个题,我太开心了。。。。
【题意】给了一颗树,询问这个树里面每个点到树上其他点的最大距离,这个题是属于树形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;
}