基准时间限制: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\n", dp[i]);
return 0;
}

51Nod 1405 树的距离之和(dp)的更多相关文章

  1. 51nod 1405 树的距离之和 树形dp

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB   收藏  关注 给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和. Input ...

  2. 51Nod - 1405 树的距离之和(树形DP)

    1405 树的距离之和 题意 给定一棵无根树,假设它有n个节点,节点编号从1到n,求任意两点之间的距离(最短路径)之和. 分析 树形DP. 首先我们让 \(1\) 为根.要开两个数组 \(up \ d ...

  3. 51Nod 1405 树的距离之和 (树dp)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405 中文题面不解释了,两次dfs,第一次自下向上,第二次自上 ...

  4. 51nod 1405 树的距离之和(dfs)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405 题意: 思路: 先求出所有点到根节点的距离,需要维护每棵子树的大小 ...

  5. 51 nod 1405 树的距离之和

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题   给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之 ...

  6. [51NOD1405] 树的距离之和(树DP)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405 (1)我们给树规定一个根.假设所有节点编号是0-(n-1 ...

  7. hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解

    题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...

  8. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  9. 51Nod 1110 距离之和最小 V3 中位数 思维

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].点P到点P[i]的带权距离 = 实际距离 ...

随机推荐

  1. Promise语法

    转自:廖雪峰的官方网站 在JavaScript的世界中,所有代码都是单线程执行的. 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行.异步执行可以用回调函数实现: ...

  2. CodeForces-1007A Reorder the Array 贪心 田忌赛马

    题目链接:https://cn.vjudge.net/problem/CodeForces-1007A 题意 给个数组,元素的位置可以任意调换 问调换后的元素比此位置上的原元素大的元素个数最大多少 思 ...

  3. Python爬虫简单入门及小技巧

    刚刚申请博客,内心激动万分.于是为了扩充一下分类,随便一个随笔,也为了怕忘记新学的东西由于博主十分怠惰,所以本文并不包含安装python(以及各种模块)和python语法. 目标 前几天上B站时看到一 ...

  4. luogu P3674 小清新人渣的本愿(莫队+bitset)

    这题是莫队维护bitset. 然而我并不会bitset以前讲过认为不考就没学 我真的太菜了. 首先维护一个权值的bitset--s. 操作3比较简单,我们可以\(\sqrt{x}\)枚举约数然后判断就 ...

  5. springboot ajax返回html

    因为拦截器 或者是 shiro  拦截登陆接口

  6. Mysql导入Sql文件时报Error Code: 2013 - Lost connection to MySQL server during query

    MySql 有时我们导入sql文件,文件过大,导致Error Code: 2013 - Lost connection to MySQL server during query这种错误 执行以下: S ...

  7. HDOJ 5008 Boring String Problem

    后缀数组+RMQ+二分 后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa Boring String Problem Time Limit: 6000 ...

  8. JavaScript中的Array对象方法调用

    方法concat for  循环与for in 循环 <html> <head> <script type="text/javascript"> ...

  9. [Perl系列—] 2. Perl 中的引用使用方法

    Perl 中的引用,为什么要使用引用? 对于熟悉C语言的开发人员来说, 指针这个概念一定不陌生. Perl 的引用就是指针,能够指向变量.数组.哈希表甚至子程序. Perl5中的两种Perl引用类型为 ...

  10. Python库之pyudev (一)

    库pyudev是libudev的python封装,libudev提拱了对本地设备的列举与查询API. 1.安装 pip install pyudev 2. 使用 2.1 开始 导入pyudev,验证库 ...