由树的直径定义可得,树上随意一点到树的直径上的两个端点之中的一个的距离是最长的...
三遍BFS求树的直径并预处理距离.......
5 1 1 2 1 3 1 1 1
3 2 3 4 4
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=20010;
struct Edge
{
  int to,next,w;
}edge[maxn*2];
int Adj[maxn],Size;
void init()
{
  memset(Adj,-1,sizeof(Adj)); Size=0;
}
void add_edge(int u,int v,int w)
{
  edge[Size].to=v;
  edge[Size].w=w;
  edge[Size].next=Adj[u];
  Adj[u]=Size++;
}
int dist_s[maxn],dist_t[maxn],dist[maxn];
int n;
bool vis[maxn];
int bfs1()
{
  int ret=1;
  queue<int> q;
  memset(vis,false,sizeof(vis));
  q.push(1);
  dist[1]=0;
  vis[1]=true;
  while(!q.empty())
    {
      int u=q.front(); q.pop();
      for(int i=Adj[u];~i;i=edge[i].next)
        {
          int v=edge[i].to;
          int c=edge[i].w;
          if(vis[v]) continue;
          dist[v]=dist[u]+c;
          vis[v]=true; q.push(v);
          if(dist[v]>dist[ret])
            ret=v;
        }
    }
  return ret;
}
int bfs2(int x)
{
  int ret=x;
  queue<int> q;
  memset(vis,false,sizeof(vis));
  q.push(x); vis[x]=true;
  dist_s[x]=0;
  while(!q.empty())
    {
      int u=q.front(); q.pop();
      for(int i=Adj[u];~i;i=edge[i].next)
        {
          int v=edge[i].to;
          int c=edge[i].w;
          if(vis[v]==true) continue;
          vis[v]=true;
          dist_s[v]=dist_s[u]+c;
          q.push(v);
          if(dist_s[v]>dist_s[ret])
            ret=v;
        }
    }
  return ret;
}
int bfs3(int x)
{
  int ret=x;
  queue<int> q;
  memset(vis,false,sizeof(vis));
  q.push(x); vis[x]=true;
  dist_t[x]=0;
  while(!q.empty())
    {
      int u=q.front(); q.pop();
      for(int i=Adj[u];~i;i=edge[i].next)
        {
          int v=edge[i].to;
          int c=edge[i].w;
          if(vis[v]==true) continue;
          vis[v]=true;
          dist_t[v]=dist_t[u]+c;
          q.push(v);
          if(dist_t[v]>dist_t[ret])
            ret=v;
        }
    }
  return ret;
}
int main()
{
  while(scanf("%d",&n)!=EOF)
    {
      init();
      memset(dist_s,0,sizeof(dist_s));
      memset(dist_t,0,sizeof(dist_t));
      memset(dist,0,sizeof(dist));
      for(int i=2;i<=n;i++)
        {
          int x,w;
          scanf("%d%d",&x,&w);
          add_edge(x,i,w);
          add_edge(i,x,w);
        }
      int s=bfs1();
      int t=bfs2(s);
      bfs3(t);
      //cout<<"s: "<<s<<"  t: "<<t<<endl;
      for(int i=1;i<=n;i++)
        {
          printf("%d\n",max(dist_s[i],dist_t[i]));
        }
    }
  return 0;
}
原文:http://www.cnblogs.com/claireyuancy/p/6871705.html