zoukankan      html  css  js  c++  java
  • 【题解】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
    ",maxlen[i]);
        }
        return 0;
    }
  • 相关阅读:
    11-15SQLserver基础--数据库之范式理论
    11-13SQLserver基础--数据库之事务
    11-11SQLserver基础--数据库之触发器
    C#中abstract和virtual区别
    virtual修饰符
    override 修饰符
    访问public
    访问修饰符protected
    访问修饰符private
    访问修饰符internal
  • 原文地址:https://www.cnblogs.com/rebirth-death2019/p/12152597.html
Copyright © 2011-2022 走看看