题意:求每个点的子树中哪一层节点数最多,如果有节点数最多不唯一,取层数最小的。

题解:dus on tree

基本想法是对每一个节点都构建一个deep数组,然后从底向上更新过来,但是这样空间复杂度和时间复杂度都会是O(n^2)无法承受。

然后向办法共用deep数组和记录其数值的数组,那么这时候对于一个节点来说,如果他每次都要重新遍历他所有的子节点,那么时间复杂度仍是O(n^2),所以考虑保留他某个儿子的火种,那当然是保留其子树最大的儿子节点了,所以每次先dfs其不是子数最大的儿子的节点,而后遍历子数最大的儿子节点,这个顺序不能反,因为你要对先遍历的清空,这是由于你共用了数组,所以每次访问前都要清空cnt数组,但是最后一个可以不清空,因为他没有别的儿子要访问了。

复杂度分析:由于重链是直接继承(大儿子最后访问不清空)的关系,也就是O(1)就可以了,考虑轻链,对于某个点来说,他一直跑一直跑到根节点,至多经过logn条轻链,因为每条轻链都会导致节点总数目*2,所以是logn条,所以总复杂度就是nlogn了

算法的关键点就是利用了重链轻链的思想,重用了数组,适用于查询所有节点的题目。

https://codeforces.com/blog/entry/44351     //codeforce博客链接

  1. #include<vector>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. const int N=1e6+;
  7. vector<int>G[N];
  8. int n,sz[N],deep[N],c[N],ans[N];
  9. void getsz(int x,int f,int dt){
  10. sz[x]=;
  11. deep[x]=dt;
  12. for(int i=;i<(int)G[x].size();++i) {
  13. int v=G[x][i];
  14. if(v==f) continue;
  15. getsz(v,x,dt+);
  16. sz[x]+=sz[v];
  17. }
  18. }
  19. int mx,id;
  20. void mdy(int x,int y){
  21. c[x]+=y;
  22. if(c[x]>mx) mx=c[x],id=x;
  23. if(c[x]==mx&&x<id) id=x;
  24. }
  25. void add(int u,int p,int x){
  26. mdy(deep[u],x);
  27. for(int i=;i<(int)G[u].size();++i){
  28. int v=G[u][i];
  29. if(v==p) continue;
  30. add(v,u,x);
  31. }
  32. }
  33. void dfs(int u,int p,bool keep){
  34. int big=-,now=;
  35. for(int i=;i<(int)G[u].size();++i) {
  36. int v=G[u][i];
  37. if(v==p) continue;
  38. if(sz[v]>now) now=sz[v],big=v;
  39. }
  40. for(int i=;i<(int)G[u].size();++i) {
  41. int v=G[u][i];
  42. if(v==big||v==p) continue;
  43. dfs(v,u,);
  44. }
  45. if(~big) dfs(big,u,);
  46. mdy(deep[u],);
  47. for(int i=;i<(int)G[u].size();++i) {
  48. int v=G[u][i];
  49. if(v==big||v==p) continue;
  50. add(v,u,);
  51. }
  52. ans[u]=id;
  53. if(!keep){
  54. mdy(deep[u],-);
  55. for(int i=;i<(int)G[u].size();++i){
  56. int v=G[u][i];
  57. if(v==p) continue;
  58. add(v,u,-);
  59. }
  60. mx=id=;
  61. }
  62. }
  63. int main(){
  64. int x,y;
  65. scanf("%d",&n);
  66. for(int i=;i<n;++i) {
  67. scanf("%d%d",&x,&y);
  68. G[x].push_back(y);
  69. G[y].push_back(x);
  70. }
  71. getsz(,,);
  72. dfs(,,);
  73. for(int i=;i<=n;++i) printf("%d\n",ans[i]-deep[i]);
  74. }

F. Dominant Indices的更多相关文章

  1. Codeforces 1009 F - Dominant Indices

    F - Dominant Indices 思路:树上启发式合并 先跑轻子树,然后清除轻子树的信息 最后跑重子树,不清除信息 然后再跑一遍轻子树,重新加回轻子树的信息 由于一个节点到根节点最多有logn ...

  2. Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)

    F. Dominant Indices 题意: 给一颗无向树,根为1.对于每个节点,求其子树中,哪个距离下的节点数量最多.数量相同时,取较小的那个距离. 题目: 这类题一般的做法是树上的启发式合并,复 ...

  3. Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并

    题意:有一棵树,对于每个点求子树中离他深度最多的深度是多少, 题解:线段树合并快如闪电,每个节点开一个权值线段树,递归时合并即可,然后维护区间最多的是哪个权值,到x的深度就是到根的深度减去x到根的深度 ...

  4. CF 1009 F Dominant Indices —— 长链剖分+指针

    题目:http://codeforces.com/contest/1009/problem/F 也可以用 dsu on tree 的做法,全局记录一个 dep,然后放进堆里,因为字典序要最小,所以再记 ...

  5. 【CF1009F】Dominant Indices(长链剖分)

    [CF1009F]Dominant Indices(长链剖分) 题面 洛谷 CF 翻译: 给定一棵\(n\)个点,以\(1\)号点为根的有根树. 对于每个点,回答在它子树中, 假设距离它为\(d\)的 ...

  6. CF1009F Dominant Indices 解题报告

    CF1009F Dominant Indices 题意简述 给出一颗以\(1\)为跟的有根树,定义\(d_{i,j}\)为以\(i\)为根节点的子树中到\(i\)的距离恰好为\(j\)的点的个数,对每 ...

  7. [CF1009F] Dominant Indices (+dsu on tree详解)

    这道题用到了dsu(Disjoint Set Union) on tree,树上启发式合并. 先看了CF的官方英文题解,又看了看zwz大佬的题解,差不多理解了dsu on tree的算法. 但是时间复 ...

  8. 【Cf Edu #47 F】Dominant Indices(长链剖分)

    要求每个点子树中节点最多的层数,一个通常的思路是树上启发式合并,对于每一个点,保留它的重儿子的贡献,暴力扫轻儿子将他们的贡献合并到重儿子里来. 参考重链剖分,由于一个点向上最多只有$log$条轻边,故 ...

  9. CF1009F Dominant Indices(启发式合并)

    You are given a rooted undirected tree consisting of nn vertices. Vertex 11 is the root. Let's denot ...

随机推荐

  1. java中Runnable和Callable的区别

    文章目录 运行机制 返回值的不同 Exception处理 java中Runnable和Callable的区别 在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是ja ...

  2. 升级vue项目中的element-ui的版本

    首先卸载项目中的element-ui 命令为: npm uninstall element-ui / cnpm uninstall element-ui 安装更新最新的element-ui 命令为 n ...

  3. C++编程入门题目--No.5

    题目: 输入三个整数x,y,z,请把这三个数由小到大输出. 程序分析: 我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换, 然后再用x与z进行比较,如果x> ...

  4. VS Code 全部快捷键一览表(巨TM全)

    常用 General 按 Press 功能 Function Ctrl + Shift + P,F1 显示命令面板 Show Command Palette Ctrl + P 快速打开 Quick O ...

  5. 数学--数论-- HDU 2601 An easy problem(约束和)

    Problem Description When Teddy was a child , he was always thinking about some simple math problems ...

  6. 图论--割点--Tarjan模板

    #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> ...

  7. Entity framework 加载多层相关实体数据

    Entity framework有3种加载数据的方式:懒汉式(Lazy loading),饿汉式(Eager loading),显示加载(Explicit loading).3种加载方式有各自的优缺点 ...

  8. python(写入 excel 操作 xlwt 模块)

    一.安装 xlwt 模块 pip install xlwt 二.excel 写入操作 这种方式只能新增或者覆盖文件写入 import xlwt # 创建一个workbook 设置编码 workbook ...

  9. 面试之JS深拷贝的实现

    在面试中你是否遇到过如下场景: Q:小朋友,你是否了解如何拷贝一个对象? R:此时,机智的你可能会想到 Object.assign({}, obj); Q:那如何深拷贝一个对象呢? R:机智的你 JS ...

  10. 前端——Vue-cli 通过UI页面创建项目

    在使用该教程创建项目时请先安装vue ui,具体安装方法请百度 1.打开CMD,输入vue ui 2.点击创建按钮,选择项目目录 3.填写项目名 4.配置项目 选择项目所需要的模块