• HDU 2196 Computer(树形dp)


    题目大意: 求树中每个点到所有叶子节点的距离的最大值是多少。

    思路: 这个题用两边dfs就可以,一遍是求当前点到子树那个方向上的最大值和次大值,另外一遍是父亲方向上的最大值。之所以要求子树方向上的次大值,是因为如果求当前点v的最长的距离的时候,子树里面的显而易见可以求出来,但是父亲方向上的就不确定了,如果父亲的取最大值的路径经过点v,那么这样求肯定就不对了,所以要求一个次大值,这时,用父亲的次大值加上父亲的权值和子树方向上的比较就行了。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 11000;
    struct Edge {
        int to, Next, len;
    };
    Edge edge[maxn * 2];
    int tot, head[maxn];
    int maxlen[maxn], smaxlen[maxn];//maxlen当前节点的子树的最大值 smaxlen次大值 
    int maxid[maxn], smaxid[maxn];//maxid当前节点取最大值时都应的儿子编号,  smaxid次大值时对应的编号 
    void init()
    {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void addedge(int u, int v, int len)
    {
        edge[tot].to = v;
        edge[tot].len = len;
        edge[tot].Next = head[u];
        head[u] = tot++;
    }
    //找出每一个节点往下的最大值和次大值 
    void dfs1(int u, int fa)//求出以u为根节点的最大距离 
    {
        
        maxlen[u] = smaxlen[u] = 0;
        for (int i = head[u]; i != -1; i = edge[i].Next)
        {
            int v = edge[i].to;
            if (v == fa)
                continue;
            dfs1(v, u);
            if (smaxlen[u] < maxlen[v] + edge[i].len)
            {
                smaxlen[u] = maxlen[v] + edge[i].len;
                smaxid[u] = v;
                if (maxlen[u] < smaxlen[u])
                {
                    swap(maxlen[u], smaxlen[u]);
                    swap(maxid[u], smaxid[u]);
                }
            }
        }
    }
    //找出从父节点过来和从当前点向下的最大值 
    void dfs2(int u, int fa)
    {
        for (int i = head[u]; i != -1; i = edge[i].Next)
        {
            int v = edge[i].to;
            if (v == fa)
                continue;
            if (v == maxid[u])//这里求的是v的而不是u的,和dfs1区分开,所以如果u取最大值时如果经过v的话,那么算从u过来的路径时要用次大值 
            {
                if (edge[i].len + smaxlen[u] > smaxlen[v])
                {
                    smaxlen[v] = edge[i].len + smaxlen[u];
                    smaxid[v] = u;
                    if (maxlen[v] < smaxlen[v])
                    {
                        swap(maxlen[v], smaxlen[v]);
                        swap(maxid[v], smaxid[v]);
                    }
                }
            }
            else//否则用最大值 
            {
                if (edge[i].len + maxlen[u] > smaxlen[v])
                {
                    smaxlen[v] = edge[i].len + maxlen[u];
                    smaxid[v] = u;
                    if (maxlen[v] < smaxlen[v])
                    {
                        swap(maxlen[v], smaxlen[v]);
                        swap(maxid[v], smaxid[v]);
                    }
                }
            }
            dfs2(v, u);
        }
    }
    
    int main()
    {
        int n;
        while (~scanf("%d", &n))
        {
            init();
            int a, b;
            for (int i = 2; i <= n; i++)
            {
                scanf("%d %d", &a, &b);
                addedge(i, a, b);
                addedge(a, i, b);
            }
            dfs1(1, 0);
            dfs2(1, 0);
            for (int i = 1; i <= n; i++)
                printf("%d
    ", maxlen[i]);
        }    
        return 0;
    }
  • 相关阅读:
    华硕笔记本无法U盘启动,快捷键识别不了
    怎么将uefi改成legacy启动|BIOS设置legacy引导模式的方法
    [CDLinux]制作U盘CDLinux系统启动盘
    重装系统时,将MBR分区转为GPT 分区
    5-Comments
    4-HTML Computer Code Elements
    3-html 缩写-地址-文字方向-引用块-题注的格式
    2-HTML Text Formatting Elements
    1-HTML Attributes
    LabVIEW--为设备添加配置文件.ini
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4773890.html
Copyright © 2020-2023  润新知