题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405

(1)我们给树规定一个根。假设所有节点编号是0-(n-1),我们可以简单地把0当作根,这样下来父子关系就确定了。

(2)定义数组num[x]表示以节点x为根的子树有多少个节点,dp[x]是我们所求的——所有节点到节点x的距离之和。
(3)在步骤(1)中,其实我们同时可以计算出 num[x],还可以计算出每个节点的深度(每个到根节点0的距离),累加全部节点深度得到的其实就是是dp[0]。
(4) 假设一个非根节点x,它的父亲节点是y, 并且dp[y]已经计算好了,我们如何计算dp[x]?  
以x为根的子树中那些节点,到x的距离比到y的距离少1, 这样的节点有num[x]个。
其余节点到x的距离比到y的距离多1,这样的节点有(n - num[x])个。
于是我们有 dp[x] = dp[y] - num[x] + (n - num[x]) = dp[y] + n - num[x] * 2
因为树的根节点dp[0]在步骤(3)已经计算出来了,根据所有的父子关系和这个上式,我们可以按照顺序计算出整个dp数组。特别像多校的一道题,或者说这类题都很类似。
 #include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#pragma comment(linker, "/STACK:10240000,10240000")
using namespace std;
using namespace __gnu_pbds; typedef long long LL;
const int maxn = ;
vector<int> G[maxn];
LL num[maxn];
LL dp[maxn];
int n; LL dfs1(int u, int p, LL d) {
int cnt = ;
num[u] = cnt;
dp[] += d;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if(v == p) continue;
num[u] += dfs1(v, u, d+);
}
return num[u];
} void dfs2(int u, int p) {
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if(v == p) continue;
dp[v] = dp[u] + n - num[v] * ;
dfs2(v, u);
}
} int main() {
//freopen("in", "r", stdin);
int u, v;
while(~scanf("%d", &n)) {
memset(num, , sizeof(num));
memset(dp, , sizeof(dp));
for(int i = ; i <= n; i++) G[i].clear();
for(int i = ; i < n; i++) {
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(, -, );
dfs2(, -);
for(int i = ; i <= n; i++) printf("%lld\n", dp[i]);
}
return ;
}

[51NOD1405] 树的距离之和(树DP)的更多相关文章

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

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

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

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

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

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

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

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 给定一棵无根树,如果它有n个节点,节点编号从1到n, 求随意两点之间的距离( ...

  5. 51 nod 1405 树的距离之和

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

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

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

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

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

  8. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  9. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

随机推荐

  1. 真实的C++单例模式举例

    把构造函数声明为protected的理由很简单,但把构造函数声明为private的原因却很少知道.   从语法上讲,任何函数如果被声明为private,这个函数就不能从外部调用,构造函数也是函数,相反 ...

  2. 菜鸟,大牛和教主三者的区别(转自hzwer)

    菜鸟,大牛和教主,三者的区别 对菜鸟来说题目有三种:会算法且能AC的,会算法但不能AC的,不会做的 对大牛来说题目有两种:会做的,不会做的 对教主来说题目有两种:能AC的,数据有错的 菜鸟提交WA了, ...

  3. Java笔试题解答和部分面试题

    面试类  银行类的问题 问题一:在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环? HashMap本身没有什么问题,有没有问题取决于你是如何使用它的.比如,你 ...

  4. js之arguments对象的使用

  5. Xcode 项目配置学习

    Xcode有四种build for 分别是: build for Running build for Testing build for Profiling build for Archiving R ...

  6. React笔记_(2)_react语法1

    这一节内容主要以了解为主. 渐渐的体会react的语法和其特性. ① htmlAndJs 混合编写 react和以往的前后台书写方式不一样. 在之前的多个语言中,讲求的是将页面代码和js代码逻辑分开, ...

  7. Temporary InMemory Tables [AX 2012]

    Temporary InMemory Tables [AX 2012] This topic has not yet been rated - Rate this topic Updated: Oct ...

  8. [ios][swift]swift 怎么去除 optional

    在转换String时要使用“!”进行拆包,用“?”则会有optional 出现

  9. Cocos2dx中的opengl使用(一)简单介绍

    引擎提供了CCGLProgram类来处理着色器相关操作,对当前绘图程序进行了封装,其中使用频率最高的应该是获取着色器程序的接口:const GLuint getProgram(); 该接口返回了当前着 ...

  10. css 前景色与背景色

    前景色:color:#990000; 背景色:background-color:red; 可以用来设置文字的前景色与背景色 <!-- 作者:纤锐出处:http://www.cnblogs.com ...