点分治小结


目录

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

引入

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

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

重心

重心是什么?

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

算法流程

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

优质内容筛选与推荐>>
1、SGU - 321 - The Spy Network
2、数据库原理精讲1
3、SYN-Flood防御方法之一Synproxy
4、ACL中通配符的灵活运用
5、基于设备唯一标识符的CAN网络临时编址方法


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn