博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[POI2008]Station
阅读量:7120 次
发布时间:2019-06-28

本文共 1292 字,大约阅读时间需要 4 分钟。

题目大意:

  给定一棵n个结点的树,求一个点x作为根,使得所有结点到x的距离和最小。

思路:

  树形DP。
  首先考虑将1作为根的情况。
  很显然我们可以用一遍O(n)的DFS预处理出每个结点所对应子树大小size和子树内每个结点到这个结点的距离和sum。
  这样也就相当于我们递推求出了以1作为根时各结点到它的距离和。
  现在考虑将根往下转移。
  假设我们现在要从u转移到v,那么显然在sum[u]的基础上,sum[v]需要变化的是(u,v)之间的连接的边。
  也就是说sum[y]=sum[x]+n-size[y]*2。
  这样我们就可以用O(n)时间将根往下转移。
  总的时间复杂度还是O(n)的。

1 #include
2 #include
3 typedef long long int64; 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x;10 }11 const int N=1000001;12 int head[N],to[N<<1],next[N<<1],sz;13 inline void add_edge(const int &u,const int &v) {14 to[++sz]=v; next[sz]=head[u]; head[u]=sz;15 to[++sz]=u; next[sz]=head[v]; head[v]=sz;16 }17 int64 sum[N],max;18 int n,size[N],root;19 void dfs(const int &x,const int &par) {20 size[x]=1;21 for(int i=head[x];i;i=next[i]) {22 const int &y=to[i];23 if(y==par) continue;24 dfs(y,x);25 size[x]+=size[y];26 sum[x]+=sum[y]+size[y];27 }28 }29 void move(const int &x,const int &par) {30 if(sum[x]>max) {31 max=sum[x];32 root=x;33 } else if(sum[x]==max&&x

 

转载于:https://www.cnblogs.com/skylee03/p/8044607.html

你可能感兴趣的文章
如何注入值到Spring bean属性
查看>>
xm list源码分析
查看>>
PHPStorm 调式JS /同时调式PHP和jS
查看>>
JavaScript中的shift()、unshift()和pop()函数
查看>>
css案例学习之div与span的区别
查看>>
大话PHP缓存头
查看>>
【Java学习笔记之三十一】详解Java8 lambda表达式
查看>>
[zt]OpenCV2.1.0的安装
查看>>
Elasticsearch——Search的基本介绍
查看>>
Vue v-bind的使用
查看>>
第 22 章 Beta
查看>>
Linux 监视文件、文件夹改动
查看>>
[Erlang 0079] RabbitMQ 初探
查看>>
36.5. height / width
查看>>
树莓派蜜罐节点部署实战
查看>>
交换知识 VLAN VTP STP 单臂路由
查看>>
svn 回滚到上一个版本shell 脚本
查看>>
UID 修改 & UID 锁死修复
查看>>
动手实践虚拟网络 - 每天5分钟玩转 OpenStack(10)
查看>>
(转) Deep Learning Resources
查看>>