/*粒子线条,鼠标移动会以鼠标为中心吸附的特效*/
cursor: url(https://files-cdn.cnblogs.com/files/zouwangblog/cursor.ico),auto;

【题解】Computer Network

Description

给你一棵N(N<=10000)个节点的树,求每个点到其他点的最大距离。

Input

第一行一个数N。
接下来若干行每行两个数k,t描述一条点k到点t的边(输入数据保证无重复边)。

Output

N行每行一个数表示每个点到其他点的最大距离。

Sample Input

5
1 2
1 3
1 4
4 5

Sample Output

2
3
3
2
3

解题思路

【TREE DP】对于每个数i,记录两个值first i和second i,起点标记中点为i,终点是某个叶子结点的次短路或者最短路。两条路径i点没有公共点,在记录深点a i.

i=max(firsi,up s+1,ss);
ui=max(up s+1,ss);
这里的ss代表是否i在first s的路径上,ss=second s+1,否则ss=first i+1.

HINT

(参考代码,非本人)

#include <cstdio>
#include <algorithm>
 
const int maxn=20000;
 
int deep[maxn+10],first[maxn+10],second[maxn+10],maxlen[maxn+10],n;
int pre[(maxn<<1)+10],now[maxn+10],son[maxn+10],tot,up[maxn+10];
 
int ins(int a,int b)
{
    tot++;
    pre[tot]=now[a];
    now[a]=tot;
    son[tot]=b;
    return 0;
}
 
int dfs(int u,int fa)
{
    int j=now[u];
    deep[u]=deep[fa]+1;
    while(j)
    {
        int v=son[j];
        if(v!=fa)
        {
            dfs(v,u);
            if(first[v]+1>second[u])
            {
                second[u]=first[v]+1;
            }
            if(first[v]+1>first[u])
            {
                second[u]=first[u];
                first[u]=first[v]+1;
            }
        }
        j=pre[j];
    }
    return 0;
}
 
int getans(int u,int fa)
{
    maxlen[u]=std::max(first[u],up[fa]+1);
    up[u]=up[fa]+1;
    if(first[u]+1==first[fa])
    {
        maxlen[u]=std::max(maxlen[u],second[fa]+1);
        up[u]=std::max(up[u],second[fa]+1);
    }
    else
    {
        maxlen[u]=std::max(maxlen[u],first[fa]+1);
        up[u]=std::max(up[u],first[fa]+1);
    }
    int j=now[u];
    while(j)
    {
        int v=son[j];
        if(v!=fa)
        {
            getans(v,u);
        }
        j=pre[j];
    }
    return 0;
}
 
int main()
{
    scanf("%d",&n);
    for(int i=1; i<n; i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        ins(a,b);
        ins(b,a);
    }
    up[0]=-1;
    first[0]=-1;
    second[0]=-1;
    dfs(1,0);
    getans(1,0);
    for(int i=1; i<=n; i++)
    {
        printf("%d\n",maxlen[i]);
    }
    return 0;
}
posted @ 2020-01-05 15:34  Empty-R  阅读(243)  评论(0编辑  收藏  举报