zoukankan      html  css  js  c++  java
  • 51Nod 1405 树的距离之和(dp)

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注
    给定一棵无根树,如果它有n个节点,节点编号从1到n, 求随意两点之间的距离(最短路径)之和。
    Input
    第一行包括一个正整数n (n <= 100000)。表示节点个数。
    后面(n - 1)行,每行两个整数表示树的边。

    Output
    每行一个整数。第i(i = 1,2,...n)行表示全部节点到第i个点的距离之和。
    Input演示样例
    4
    1 2
    3 2
    4 2
    Output演示样例
    5
    3
    5
    5

    思路:

    首先,任选一个节点。设定为树的根。

    用num[x]表示以节点x为根的子树的节点总数(包括x自身)

    假如设定节点1为根。则先求出dp[1],表示全部节点到节点1的距离之和。

    对根而言也是全部节点的深度之和。


    若x是y的子结点,则有

    dp[x] = dp[y] + (n-num[x]) - num[x];

    由于x为根的子树的全部节点到x的距离比到y的距离少1,所以减num[x]

    其余节点到x的距离比到y的距离多1,所以加 n-num[x]


    代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #pragma comment(linker, "/STACK:10240000,10240000")//递归太深,导致爆栈,所以使用扩栈语句
    using namespace std;
    
    const int N = 100009;
    int dp[N] = {}, num[N];
    vector<int> p[N];
    bool f[N] = {};
    
    void dfs(int s, int depth)
    {
        int len = p[s].size();
        f[s] = 1;
        num[s] = 1;
        dp[1] += depth;
        for(int i=0; i<len; i++)
        {
            if(!f[p[s][i]])
            {
                dfs(p[s][i], depth+1);
                num[s] += num[p[s][i]];
            }
        }
    }
    
    void solve(int s, int n)
    {
        int len = p[s].size();
        f[s] = 1;
        for(int i=0; i<len; i++)
        {
            if(!f[p[s][i]])
            {
                dp[p[s][i]] = dp[s]+n-num[p[s][i]]*2;
                solve(p[s][i], n);
            }
        }
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
        for(int i=1; i<n; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            p[a].push_back(b);
            p[b].push_back(a);
        }
        dfs(1, 0);
        memset(f, 0, sizeof(f));
        solve(1, n);
        for(int i=1; i<=n; i++)
            printf("%d
    ", dp[i]);
        return 0;
    }


  • 相关阅读:
    BZOJ 1412: [ZJOI2009]狼和羊的故事
    Bzoj 2443: [Usaco2011 Open]奇数度数
    Bzoj 1101: [POI2007]Zap
    BZOJ 2186: [Sdoi2008]沙拉公主的困惑
    BZOJ 4804: 欧拉心算 欧拉函数
    Luogu P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
    Luogu P3000 [USACO10DEC]牛的健美操Cow Calisthenics
    BZOJ 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛
    BZOJ 3297: [USACO2011 Open]forgot
    BZOJ 2456: mode
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6999985.html
Copyright © 2011-2022 走看看