题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和。

题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小、树上前缀和。第二遍 dfs 遍历这棵树,求出各个点的距离和。

对于遍历到的任意一个节点 i,对于与之相邻的节点 j 来说,答案贡献由 i 到 j 转移首先减小了 \(size[j]*1\),同时增加了 \((n-size[j])*1\),因此可以直接得到\(dp[j]=dp[i]+n-size[j]*2\)。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} struct node{
int nxt,to;
}e[maxn<<1];
int tot=1,head[maxn];
int n,size[maxn],sum[maxn],dp[maxn]; inline void add_edge(int from,int to){
e[++tot]=node{head[from],to},head[from]=tot;
} void read_and_parse(){
n=read();
for(int i=1;i<n;i++){
int from=read(),to=read();
add_edge(from,to),add_edge(to,from);
}
} void dfs1(int u,int fa){
size[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa)continue;
sum[v]=sum[u]+1;
dfs1(v,u);
size[u]+=size[v];
}
dp[1]+=sum[u];
} void dfs2(int u,int fa){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa)continue;
dp[v]=dp[u]+n-(size[v]<<1);
dfs2(v,u);
}
} void solve(){
dfs1(1,0),dfs2(1,0);
for(int i=1;i<=n;i++)printf("%d\n",dp[i]);
} int main(){
read_and_parse();
solve();
return 0;
}

【51Nod1405】树上距离和 二次扫描与换根法的更多相关文章

  1. 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)

    写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...

  2. poj 3585 Accumulation Degree(二次扫描和换根法)

    Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...

  3. 【POJ3585】Accumulation Degree 二次扫描与换根法

    简单来说,这是一道树形结构上的最大流问题. 朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是\(O(n^2)\) 但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少 ...

  4. poj3585 树形dp 二次扫描,换根法模板题

    #include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...

  5. POJ3585 Accumulation Degree(二次扫描与换根法)

    题目:http://poj.org/problem?id=3585 很容易想出暴力.那么就先扫一遍. 然后得到了指定一个根后每个点的子树值. 怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前 ...

  6. poj - 3585(二次扫描与换根法)

    周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...

  7. $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法

    Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...

  8. [LuoguP1829]Crash的文明表格(二次扫描与换根+第二类斯特林数)

    Solution: ​ 由于 \[ x^m = \sum_{i=0}^m{~m~\choose i}{~x~\brace i}i! \] ​ 将所求的式子化成这样,挖掘其性质,考虑是否能从儿子转移(或 ...

  9. POJ - 3585 树上最大流 换根法

    题意:给出一棵树,边上有容量限制,求以任一点作为根和源点,叶子作为汇点的最大流的最大值 首先上网络流等于找死 树形DP可以\(O(n)\)求出以某点\(u\)为根的最大流,只需设\(f[u]=\sum ...

随机推荐

  1. Spark Streaming简介及原理

    简介: SparkStreaming是一套框架. SparkStreaming是Spark核心API的一个扩展,可以实现高吞吐量的,具备容错机制的实时流数据处理. 支持多种数据源获取数据: Spark ...

  2. Docker容器学习梳理 - Volume数据卷使用

    之前部署了Docker容器学习梳理--基础环境安装,接下来看看Docker Volume的使用. Docker volume使用 Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker ...

  3. 定时备份windows机器上的文件到linux服务器上的操作梳理(rsync)

    由于需要对网络设备做备份,备份文件是放到windows机器上的.现在需要将备份数据同步到linux备份机器上,想到的方案有三种: 1)将windows的备份目录共享出来,然后在linux服务器上进行挂 ...

  4. Daily Scrum- 12/23

    Meeting Minutes 与Travis和Zhongqiu讨论了Beta的Feature以及更长期的计划: 讨论了一些使用及设计上的Bug (Feature); 开始了新的开发周期: Burnd ...

  5. 运行scrapy crawl (文件名)时显示invalid syntax和no modle 'win32api'解决方案

    使用pycharm爬取知乎网站的时候,在terminal端输入scarpy crawl zhihu,提示语法错误,如下: 原因是python3.7中将async设为关键字,根据错误提示,找到manho ...

  6. nodejs框架对比

    最近想实操nodejs,在选择框架的时候,查阅后大致整理为如下表格内容. 此处列举下才开始使用eggjs框架: 1.其基于koa开发: 2.若为企业级项目,用其脚手架egg-inint搭建会快很多,后 ...

  7. CAS的应用场景

    国外应用(需FQ尝试): 来自CAS官网推荐的Demo http://casserver.herokuapp.com/cas/login https://casserver.herokuapp.com ...

  8. JDK学习AbstractQueuedSynchronizer和AbstractQueuedLongSynchronizer

    AbstractQueuedLongSynchronizer类是扩展自AbstractQueuedSynchronizer的,实现了java.io.Serializable接口. 其中提到的wait ...

  9. idHTTP 向网站发送json格式数据

    idHTTP 向网站发送json格式数据 var rbody:tstringstream; begin rbody:=tstringstream.Create('{"name":& ...

  10. vue的自定义组件和组件传值

    <div id="app"> <div>{{pmessage}}</div> //父组件 <child :message="pm ...