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中。这就是递归求解节点大小的原理。


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

    你掌握了吗?

  • 相关阅读:
    python中的unlink
    if
    python中if __name__ == '__main__'
    rename函数
    win2003的密钥
    url
    python中的os.stat
    python中的mysql
    防火墙
    网址
  • 原文地址:https://www.cnblogs.com/riced/p/13778888.html
Copyright © 2011-2022 走看看