zoukankan      html  css  js  c++  java
  • 点分治小结

    最近学了学点分治,毕竟OJ上都搞了个专题了。

    引入

    以一个点为界限,将一棵树分成若干个子树,当划分到一定规模,就对每个子树分别进行求解

    What is 点分治?

    我们为了保证时间,所以要使子树大小尽量小。
    如何找到最优的点呢?就是重心!

    重心

    重心是什么?

    树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。——百度百科

    算法流程

    1.求当前树重心。
    2.计算答案。
    3.走到相邻未操作的节点进行第1步。

    求重心

    暴力(O(n)),找到一个点,使得所连子树的大小的最大值最小。
    (bz)数组表示其有没有走过(走过就不是当前树了)

    void getrt(int x, int fa)
    {
    	siz[x] = 1; son[x] = 0;
    	for (int p = tail[x], v; p; p = e[p].fr)
    	{
    		v = e[p].v;
    		if (v == fa || bz[v]) continue;
    		getrt(v, x);
    		if (son[x] < siz[v]) son[x] = siz[v];
    		siz[x] += siz[v];
    	}
    	if (son[x] < tot - siz[x]) son[x] = tot - siz[x];
    	if (son[x] < son[rt]) rt = x;
    }
    

    时间复杂度

    可证明为(O(log^n_2))
    由于重心有一个性质:
    树的重心的每棵子树大小一定小于等于(n/2)
    所以就可以证明啦。

    例题

    详见OJ

    转载需注明出处。
  • 相关阅读:
    Shell脚本编程-02-----shell编程之条件语句
    ELK 简介
    Linux 下的网卡文件配置
    Tomcat 简介
    Docker 基本操作
    zabbix 介绍
    CentOS 上搭建 Kubernetes 集群
    Docker 简介
    yum 源的配置安装
    Docker 入门
  • 原文地址:https://www.cnblogs.com/jz929/p/11296475.html
Copyright © 2011-2022 走看看