题意:给你一个树,求任意点对的最长距离
思路:首先任意选取一个点求一次DFS求出树上直径的一个端点,然后以该端点再一次DFS求出另一个树直径端点,然后再以该端点为起点DFS一波,每次都更新d数组。
原理:树上任意某个节点到树上任意节点的最远距离的端点一定会是树上直径的两个端点之一
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 10010
#define LL long long
int cas=1,T;
struct Edge
{
int v,w;
Edge(int vv,int ww):v(vv),w(ww){}
};
int d[maxn];
int maxlen;
vector<vector<Edge> >e;
int End=0;
void dfs(int u,int fa,int len)
{
if (len>maxlen)
maxlen=len,End=u;
for (int i = 0;i<e[u].size();i++)
{
int v = e[u][i].v,w=e[u][i].w;
if (v==fa)
continue;
dfs(v,u,len+w);
d[v]=max(d[v],len+w);
}
}
int main()
{
int n;
while (scanf("%d",&n)!=EOF)
{
e.clear();
e.resize(n+2);
for (int i = 2;i<=n;i++)
{
int v,w;
scanf("%d%d",&v,&w);
e[i].push_back(Edge(v,w));
e[v].push_back(Edge(i,w));
}
memset(d,0,sizeof(d));
maxlen=0;
dfs(1,-1,0);
dfs(End,-1,0);
dfs(End,-1,0);
for (int i = 1;i<=n;i++)
printf("%d\n",d[i]);
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}