对于树上任意一点来讲,相距最远的点要么是从父节点走过来的,要么就是从儿子节点中走过来。因此可以先进行一次自下向上的dp,处理出从儿子节点过来的最远点的距离。然后再进行一次自上而下的dp,同时传入从父亲节点过来时最远点的距离,这样和从儿子节点过来的最远点的距离对比一下,就可以找到距这个点最远的点的距离了。

INF = 0x3f3f3f3f
N = 0
g = [[]]
dp = []
ans = []
res = 0

def input():
    global N, g
    N = int(raw_input())
    g = [[] for i in range(N + 1)]
    for i in range(2, N + 1):
        x = int(raw_input())
        g[x].append(i), g[i].append(x)

def bottom_up(x, px):
    global dp, g
    dp[x] = 0
    for y in g[x]:
        if y == px: continue
        bottom_up(y, x)
        dp[x] = max(dp[x], dp[y] + 1)

def top_down(x, px, dis):
    global dp, res, ans, g
    t = max(dp[x], dis)
    if t < res:
        res = t
        ans = [x]
    elif t == res: ans.append(x)
    opt = [dp[i] + 1 for i in g[x]]
    for i in range(len(opt) - 2, -1, -1):
        opt[i] = max(opt[i], opt[i + 1])
    i = 0
    t = dis
    for y in g[x]:
        i += 1
        if y == px: continue
        ndis = t
        if i < len(opt) and opt[i] > ndis: ndis = opt[i]
        top_down(y, x, ndis + 1)
        t = max(t, dp[y] + 1) 

def process():
    global N, dp, res, ans
    dp = [-1 for i in range(N + 1)]
    bottom_up(1, -1)
    res = 0x3f3f3f3f
    top_down(1, -1, 0)
    ans.sort()
    for i in ans: print i,
    print

#main
input()
process()

 

posted on 2013-03-15 23:36  Staginner  阅读(488)  评论(0编辑  收藏  举报