zoukankan      html  css  js  c++  java
  • [模板] 点分治

    建议去别的地方看一下点分治的具体步骤之后再来看代码

    我的代码有详细解释

    //每次到子树中找子树重心(即遍历一遍子树)O(n),而共需找log次,因为每次都把树分成了两段
    //=>点分治复杂度O(nlogn)
    struct pp
    {
        int next,to,w;
    }edge[_];
    void getroot(rg int i,rg int dad,rg int s)//找重心   //s:该联通块大小
    {
        size[i]=1;//该点子树大小
        F[i]=0;//最大儿子子树大小
        dfn[i]=++dfns;
        for(rg int j=record[i];j;j=edge[j].next)
        {
            rg int to=edge[j].to;
            if(to!=dad&&!passed[to])//passed[]数组只标记找过的重心,因为要把树隔开
            {
                getroot(to,i);
                F[i]=max(F[i],size[to]);
                size[i]+=size[to];
            }
        }
        F[i]=max(F[i],s-size[i]);//别忘了该点父亲也算是其儿子,只不过(to!=dad)阻止了遍历回去,在这里用树的总大小(s)减去该点size->求出其父所在子树大小                                                                                           _  _
        root=F[i]<F[root]?i:root;//找到重心,用root这个词是因为不知道重心的英文是什么(   v   )
    }
    void dfs(rg int i,rg int all)
    {
        // FFF : 让火焰净化一切!!!
        passed[i]=1;//dfs函数是从重心出发的,为了隔开子树,把其标记为走过
        for(rg int j=record[root];j;j=edge[j].next)
        {
            rg int to=edge[j].to;
            if(!passed[to])
            {
                rg int s;
                if(dfn[to]>dfn[i])s=size[to];//初始化!!!
                else s=all-size[i];
                root=0;//初始化!!!
                dfns=0;//初始化!!!
                getroot(to,0,s);
                dfs(root,s);
            }
        }
    }
    //        F[0]=n;  !!!!
  • 相关阅读:
    LinQ Group By
    sql server 还原数据库后,删除用户,提示数据库主体在该数据库中拥有架构,无法删除解决方法
    各种网站资源
    Easyui TreeGrid数据源
    MVC中创建自定义视图的t4模板
    栈溢出练习
    Stack Canary
    攻防世界pwn之新手练习区
    开源 PetaPoco 扩展~一个小型轻巧的ORM~
    linux调度全景指南
  • 原文地址:https://www.cnblogs.com/c-wen/p/9332821.html
Copyright © 2011-2022 走看看