zoukankan      html  css  js  c++  java
  • HDU-2196-Computer(树上DP)

    链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=2196

    题意:

    A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

    Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.

    思路:

    可以一眼看出可以用换根.
    但是无法处理是否上一个节点的最长距离正好选了某个子节点,看了题解发现可以去记录最长的和次长的,长见识了。。
    一次DFS求出有向的每个点往下的最长距离和次长距离,然后再一次DFS,求出往父节点扩展的长度。

    代码:

    // #include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<string.h>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const int MOD = 1e9;
    const int MAXN = 1e4+10;
    
    struct Node
    {
        int x;
        int v;
    };
    vector<Node> G[MAXN];
    int Dp1[MAXN], Dp2[MAXN], Dp3[MAXN];
    int Max[MAXN];
    int n;
    
    void Dfs1(int x, int pre)
    {
        Dp1[x] = Dp2[x] = 0;
        for (int i = 0;i < G[x].size();i++)
        {
            int node = G[x][i].x;
            if (node == pre)
                continue;
            Dfs1(node, x);
            if (Dp1[node]+G[x][i].v > Dp1[x])
            {
                Dp1[x] = Dp1[node]+G[x][i].v;
                Max[x] = node;
            }
        }
        for (int i = 0;i < G[x].size();i++)
        {
            int node = G[x][i].x;
            if (node == Max[x])
                continue;
            Dp2[x] = max(Dp2[x], Dp1[node]+G[x][i].v);
        }
    }
    
    void Dfs2(int x, int pre)
    {
        for (int i = 0;i < G[x].size();i++)
        {
            int node = G[x][i].x;
            if (node == pre)
                continue;
            if (node != Max[x])
                Dp3[node] = max(Dp1[x]+G[x][i].v, Dp3[x]+G[x][i].v);
            else
                Dp3[node] = max(Dp2[x]+G[x][i].v, Dp3[x]+G[x][i].v);
            Dfs2(node, x);
        }
    }
    
    int main()
    {
        // freopen("test.in", "r", stdin);
        int t, cas = 0;
        // scanf("%d", &t);
        while(~scanf("%d", &n))
        {
            for (int i = 1;i <= n;i++)
                G[i].clear();
            memset(Dp1, 0, sizeof(Dp1));
            memset(Dp2, 0, sizeof(Dp2));
            int a, l;
            for (int i = 2;i <= n;i++)
            {
                scanf("%d%d", &a, &l);
                G[a].push_back(Node{i, l});
                G[i].push_back(Node{a, l});
            }
            Dfs1(1, -1);
            Dfs2(1, -1);
            for (int i = 1;i <= n;i++)
                printf("%d
    ", max(Dp1[i], Dp3[i]));
        }
    
        return 0;
    }
    
  • 相关阅读:
    JS中使用正则表达式封装的一些常用的格式验证的方法-是否外部url、是否小写、邮箱格式、是否字符、是否数组
    Java中操作字符串的工具类-判空、截取、格式化、转换驼峰、转集合和list、是否包含
    Cocos2d-x 2.0 自适应多种分辨率
    应用自定义移动设备外观
    为移动设备应用程序创建外观
    【2020-11-28】人生十三信条
    【2020-11-27】事实证明,逃避是下等策略
    Python 之web动态服务器
    Python 之pygame飞机游戏
    PHP 之转换excel表格中的经纬度
  • 原文地址:https://www.cnblogs.com/YDDDD/p/12022396.html
Copyright © 2011-2022 走看看