虽然题目描述的比较乱,但依稀看的出来,大意是给出一棵树,对每个节点求与它距离最远的点到它的距离。
  对每个节点保存三个距离——向上扩展的最大距离(就是节点的深度)、向下扩展的最大距离(以及经过的第一个子节点)、向下扩展的次大距离(以及经过的第一个子节点),下面分别用dis[i,0],dis[i,1],dis[i,2]表示(经过的节点用point[i,1],point[i,2]表示),节点i,j之间的距离用g[i,j]表示。
  dis[i,0]=dis[parent[i],0]+g[parent[i],i];
  dis[i,1]=max{dis[j,1]+g[i,j] | while j is a child of i};
  dis[i,2]=the_2nd_largest_of{dis[j,1]+g[i,j] | while j is a child of i};(这个不太好表述……)
  最后的最大距离用maxdis[i]表示。
  maxdis[i]=max{dis[i,0], dis[i,1], dis[parent[i],1]+g[parent[i],i]+g[parent[i],point[parent[i],1]] (if point[parent[i],1]<>i), dis[parent[i],2]+g[parent[i],i]+g[parent[i],point[parent[i],2]] (if point[parent[i],2]<>i)};
  树用邻接表实现就可以了。
  编了一组数据:
15
1 3
1 5
1 4
2 2
2 7
3 1
4 3
4 6
7 8
8 4
8 9
9 3
9 5
10 10
  发现求maxdis的算法是错误的。
  dis[i,0]改为表示经过父节点扩展出来的最大距离。
  dis[i,0]=max{dis[parent[i],0]+g[parent[i],i], dis[parent[i],1]+g[parent[i],i] (if point[parent[i],1]<>i), dis[parent[i],2]+g[parent[i],i] (if point[parent[i],2]<>i)}
  maxdis[i]=max{dis[i,0], dis[i,1]}
  算法过程是,先求dis[i,1]和dis[i,2],然后求dis[i,0],最后求maxdis。

  Submit 1: MLE on 13。把list改成vector。
  Submit 2: AC。以后我再也不用list了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <cstdio>
#include <list>
#include <algorithm>
#include <vector>
using namespace std;
 
struct treenode
{
    int len;
    vector<int> child;
};
 
treenode tree[10001];
int dis[10001][3]={{0}},point[10001][3]={{0}};
 
void get_dis12(int i,int p)
{
    //dis[i][1]=0; point[i][1]=0;
    //dis[i][2]=0; point[i][2]=0;
    for (vector<int>::iterator j=tree[i].child.begin();j!=tree[i].child.end();++j)
    {
        get_dis12(*j,i);
        if (dis[*j][1]+tree[*j].len>dis[i][1])
        {
            dis[i][2]=dis[i][1]; point[i][2]=point[i][1];
            dis[i][1]=dis[*j][1]+tree[*j].len; point[i][1]=*j;
        }
        else if (dis[*j][1]+tree[*j].len>dis[i][2])
        {
            dis[i][2]=dis[*j][1]+tree[*j].len; point[i][2]=*j;
        }
    }
}
 
void get_dis0(int i,int p)
{
    dis[i][0]=max(dis[p][0]+tree[i].len,max((dis[p][1]+tree[i].len)*(point[p][1]!=i),(dis[p][2]+tree[i].len)*(point[p][2]!=i)));
    for (vector<int>::iterator j=tree[i].child.begin();j!=tree[i].child.end();++j)
    {
        get_dis0(*j,i);
    }
}
 
int main()
{
    int n;
    scanf("%d",&n);
    for (int i=2;i<=n;++i)
    {
        int p;
        scanf("%d%d",&p,&tree[i].len);
        tree[p].child.push_back(i);
    }
    tree[1].len=tree[0].len=0;
    get_dis12(1,0);
    get_dis0(1,0);
    for (int i=1;i<=n;++i)
    {
        //printf("%d %d %d ",dis[i][0],dis[i][1],dis[i][2]);
        printf("%d\n",max(dis[i][0],dis[i][1]));
    }
    return 0;
}