基准时间限制: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. (转)Java 虚拟机体系结构

    来源:http://hxraid.iteye.com/blog/676235 众所周知,Java源代码被编译器编译成class文件.而并不是底层操作系统可以直接执行的二进制指令(比如Windows O ...

  2. 模块-时间模块(new)

    模块-时间模块 导入: import time 方法: _STRUCT_TM_ITEMS __doc__ __loader__ __name__ __package__ __spec__ altzon ...

  3. Linux下重启mysql数据库的方法

    原文地址:Linux下重启mysql数据库的方法作者:于士博的视频教程 方法一: 命令: [root@localhost /]# /etc/init.d/mysql   start|stop|rest ...

  4. vue-cli3+typescript+路由懒加载报错问题

    vue-cli3的版本是3.4.1 出现的情况是网页显示正常,但是终端一直提示找不到模块: 如果去掉路由懒加载的方式,就没有报错: 原因是以前我们习惯直接写文件名而不加后缀, 现在使用ts时就需要写v ...

  5. BZOJ 4472 [Jsoi2015]salesman(树形DP)

    4472: [Jsoi2015]salesman Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 417  Solved: 192[Submit][St ...

  6. Python 中多线程之 _thread

    _thread模块是python 中多线程操作的一种模块方式,主要的原理是派生出多线程,然后给线程加锁,当线程结束的 时候取消锁,然后执行主程序 thread 模块和锁对象的说明 start_new_ ...

  7. mysql日期加减运算

    MySQL 日期类型MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 --------- ...

  8. Android群英传-拼图游戏puzzle-6点吐槽

    一.缘由  经常写文章,混了一些C币.最近在深入学习Android应用开发,就从商城里买了一本<Android群英传>.这本书的内容,不是纯粹的入门那种,分几个章节,重点讲解Activit ...

  9. 推断扫描后的内容是否是URL

    扫描的明明是Url.竟然当文本给处理了,看来正则没有通过. 扫描二维码后,我參考了QQ的效果.分了三种:网页地址.文件下载地址,文本信息:为了实现这样的效果.我 发现有非常多url非常奇葩.所以就想找 ...

  10. OCUI界面设计:滚动视图与分页控件初探

    滚动视图(UIScrollView) 简单介绍 1.UIScrollView滚动视图能够排列并显示超出自身显示范围的内容. 2.UIScrollView内部整合了多种手势来达到丰富的界面展示效果. 3 ...