求树上每个点能到达的最远距离,刚开始,就想找到树上最远的两个个点,那么树上的每一个点能到达的最远距离就是到这两个点的距离的大的那一个,(后来发现树上最远的两个个点的距离就叫树的直径)。
写了三个dfs,先求出树上最远的距离,肯定是直径的一个端点,然后再以这端点为根,再跑一次dfs,求出另一个端点,顺便记录到每个点的距离,找出另一个端点,为根跑一遍dfs,记录出另一个端点到每个点的距离,取较大值即可。
不过貌似还有更好的办法,
我的写法:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=10005;
int s,t,ma,tmp,n;
struct node
{
int nxt,to,w;
}edge[N<<1];
int head[N],cnt;
int ss[N],tt[N];
void add(int u,int v,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs(int u,int pre,int d)
{
if(d>ma)
{
ma=d;
tmp=u;
}
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==pre) continue;
dfs(v,u,d+edge[i].w);
}
}
void dfs_1(int u,int pre,int d)
{
if(d>ma)
{
ma=d;
tmp=u;
}
ss[u]=d;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==pre) continue;
dfs_1(v,u,d+edge[i].w);
}
}
void dfs_2(int u,int pre,int d)
{
tt[u]=d;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==pre) continue;
dfs_2(v,u,d+edge[i].w);
}
}
int main()
{
while(~scanf("%d",&n))
{
cnt=0;
memset(head,0,sizeof(head));
int u,w;
for(int i=2;i<=n;i++)
scanf("%d%d",&u,&w),add(i,u,w),add(u,i,w);
ma=-1;
dfs(1,0,0);
s=tmp;ma=-1;
dfs_1(s,0,0);
t=tmp;
dfs_2(t,0,0);
for(int i=1;i<=n;i++)
printf("%d\n",max(ss[i],tt[i]));
}
}