2019.01.14 codeforces685B. Kay and Snowflake(树形dp)
2024-10-18 02:42:03
传送门
题意简述:给出一棵树,求每个子树的重心。
首先通过画图可以观察出一个性质,我们从叶子结点向根节点递推重心的话重心的位置是不会下降的。
然后由于一个点的重心要么是自己,要么在重儿子子树内,因此如果重心不是自己,我们从重儿子子树的重心向自己爬统计答案就行了,由于重心不会下降因此时间复杂度O(n)O(n)O(n)
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=3e5+5;
int n,q,siz[N],fa[N],dep[N],hson[N],ans[N];
vector<int>e[N];
void dfs1(int p){
siz[p]=1;
for(ri i=0,v;i<e[p].size();++i){
v=e[p][i];
fa[v]=p,dep[v]=dep[p]+1,dfs1(v),siz[p]+=siz[v];
if(siz[v]>siz[hson[p]])hson[p]=v;
}
}
void dfs2(int p){
if(!hson[p]){ans[p]=p;return;}
for(ri i=0;i<e[p].size();++i)dfs2(e[p][i]);
if(siz[hson[p]]*2<=siz[p])ans[p]=p;
else for(ri v=ans[hson[p]];v!=p;v=fa[v])if(max(siz[hson[v]],siz[p]-siz[v])*2<=siz[p]){ans[p]=v;break;}
}
int main(){
n=read(),q=read();
for(ri i=2;i<=n;++i)e[read()].push_back(i);
dfs1(1),dfs2(1);
while(q--)cout<<ans[read()]<<'\n';
return 0;
}
最新文章
- jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on
- java动态代理浅析
- 使用ECMAscript5中的forEach函数遍历数组
- spring security源码分析之web包分析
- jquery 验证插件 validate
- wordpress博客搬家心得
- [C++程序设计]变量的存储类别
- 批量自动更新SVN版本库 - Windows
- 【转载】目前主流过滤XSS的三种技术
- Apple watch ,小米微信通知
- Java接口自动化测试之Maven项目的创建(一)
- 如何突破Ue4材质编辑器没有Pass的概念
- [转java发送http的get、post请求]
- Python多线程基本操作
- Linux应急响应思路详谈
- BZOJ P4720[Noip2016]换教室____solution
- c# windows service 程序
- centos7安装后的防火墙问题
- 推广Facebook技巧
- ubuntu 关闭触控板
热门文章
- UNITY3D 2D物流流体插件下载|Liquid Physics 2D
- JSP跳转到指定位置
- RPC 框架之 Goole protobuf
- 【 python】输出随机的字符或数字
- log4j 产生的日志位置设置和catalina.home、catalina.base
- 利用jenkins+saltstack+sh 修改nginx配置文件并重新加载
- WorkerMan源码分析(resetStd方法,PHP中STDIN, STDOUT, STDERR的重定向)
- [Mysql]——通过例子理解事务的4种隔离级别(转)
- Selenium + Python + Firefox
- rem初始化