zoukankan      html  css  js  c++  java
  • 树的基础:树的重心

    Dev.c++树的基础:树是一种特殊的图,有一些特殊的性质,重心就是其一。可以用它的定义求解。

    声明:感谢oi-wiki所提供的代码。在下***进行了一点点修改。这里先贴出oi-wiki提供的源代码。

    声明:感谢大佬zhnzh提供的帮助。一些用词和技术方面是它所提供的。若有出错,请在评论区提出

    再次声明:如果有错,不要怪我哟不要脸的

    // 这份代码默认节点编号从 1 开始,即 i ∈ [1,n]
    int size[MAXN],  // 这个节点的“大小”(所有子树上节点数 + 该节点)
        weight[MAXN],  // 这个节点的“重量”
        centroid[2];   // 用于记录树的重心(存的是节点编号)
    void GetCentroid(int cur, int fa) {  // cur 表示当前节点 (current)
      size[cur] = 1;
      weight[cur] = 0;
      for (int i = head[cur]; i != -1; i = e[i].nxt) {
        if (e[i].to != fa) {  // e[i].to 表示这条有向边所通向的节点。
          GetCentroid(e[i].to, cur);
          size[cur] += size[e[i].to];
          weight[cur] = max(weight[cur], size[e[i].to]);
        }
      }
      weight[cur] = max(weight[cur], n - size[cur]);
      if (weight[cur] <= n / 2) {  // 依照树的重心的定义统计
        centroid[centroid[0] != 0] = cur;
      }
    }
    

    同时贴出我讲解所需的代码


    int size[MAXN],  // 这个节点的“大小”(所有子树上节点数 + 该节点)
        weight[MAXN],  // 记录最大子树 
        centroid[2];   // 用于记录树的重心(存的是节点编号)
    void GetCentroid(int u, int fa) {  // u 表示当前节点 (current)
    	size[u] = 1;
    	weight[u] = 0;
    	for (int i = head[u]; i != -1; i = e[i].nxt) {
    		if (e[i].to != fa) {  // e[i].to 表示这条有向边所通向的节点。
          		GetCentroid(e[i].to, u);
          		size[u] += size[e[i].to];
          		weight[u] = max(weight[u], size[e[i].to]);
        	}
        }
        weight[u] = max(weight[u], n - size[u]);
    	if (weight[u] <= n / 2) {  // 依照树的重心的定义统计
    		centroid[centroid[0] != 0] = u;//这是一个小小的优化
      	}
    }
    

    因为对于树上的每一个点,计算其所有子树中最大的子树节点数,这个值最小的点就是这棵树的重心;
    所以这里利用这个计算重心。
    这里先将整棵树遍历一遍,遍历过程中,每个节点利用递归将它的子树递归出来(至于怎么弄得等会解释)。
    然后算出这棵树上最大的子树,不断的更新它的重心就可以了。
    这里要重点解释一下递归求解子树大小。


    可以看到他在循环结束后用size记录下节点的大小,当递归到边界时,size为1.
    返回上去时,size会加上边界的size。再返回,又会让这个节点的size加上他的孩子的size。
    以此类推,他会把整颗子树的size都遍历出来,然后加到这个节点的size中。这就是递归求解节点大小的原理。


    到现在为止,树的基础部分都讲完了。

    你掌握了吗?

  • 相关阅读:
    【Language】 TIOBE Programming Community Index for February 2013
    【diary】good health, good code
    【web】a little bug of cnblog
    【Git】git bush 常用命令
    【web】Baidu zone ,let the world know you
    【diary】help others ,help yourself ,coding is happiness
    【Git】Chinese messy code in widows git log
    【windows】add some font into computer
    SqlServer启动参数配置
    关于sqlserver中xml数据的操作
  • 原文地址:https://www.cnblogs.com/riced/p/13778888.html
Copyright © 2011-2022 走看看