点、边分治总结

不同之处:

边分治对菊花图的情况复杂度会退化,所以需要重新建图(添加虚点),使其变成二叉树。!!注意:添加的虚点不能影响原答案,假如只考虑距离,那么下图中的 1-6, 6-3, 6-7, 7-4, 7-5 的边权应当为 0
在这里插入图片描述
重建完成后,最多 4 * n 个结点

重建树的代码

void rebuild(int p,int fa){
    int last = 0;
    for(int i = Inihead[p]; ~i;i = Iniedge[i].nex){		///Iniedge 为原图
        int v = Iniedge[i].v,w = Iniedge[i].w;
        if(v == fa) continue;
        if(!last) {
            reAddEdge(p,v,w);		///reAddEdge(u,v,w),直接建立正反向边
            last = p;
        }
        else {
            int k = ++ cpyn;		///初始时 cpyn == n
            reAddEdge(last,k,0);
            reAddEdge(k,v,w);
            last = k;
        }
        rebuild(v,p);
    }
}

相同之处:

每一次都找树重心(中心边),将所有的路径都分成是否经过树重心(中心边),假设经过为情况1,未经过

情况2,那么树分治也就是处理完情况1后,递归分治 (情况2)

对情况1:

需要做的就是处理所有点到树重心(或者中心边的 u,v)  如距离(复杂度 为O(当前连通块大小))等的信息。。。。最好还是写几个题,能够理解更深

寻找重心代码:

  /// 调用时 sum 的值为 n (n 为结点总数),mi 为 inf,最后 rt 的得到的重心
void getroot(int &mi, int &rt, int p, int fa, int sum) {
    int maxx = 0;
    sonnum[p] = 1;
    for (int i = head[p]; ~i; i = edge[i].nex) {
        int v = edge[i].v;
        if (v == fa || vis[v]) continue;
        getroot(mi, rt, v, p, sum);
        sonnum[p] += sonnum[v];
        maxx = max(maxx,sonnum[v]);
    }
    if (mi > max(maxx, sum - sonnum[p])) {
        mi = max(maxx, sum - sonnum[p]);
        rt = p;
    }
}

寻找中心边代码:

/// 调用时 sum 的值为 cpyn(cpyn 为重建树后的结点总数),minn 为 inf,最后 rt 的得到的中心边
void getroot(int &minn,int &rt,int p,int fa,int sum){
    sonnum[p] = 1;
    for(int i = head[p]; ~i;i = edge[i].nex){
        int v = edge[i].v;
        if(v == fa || vis[i >> 1]) continue; ///存边的时候. 0、1 为一组,1、2为一组。故标记时标记i>>1即可
        getroot(minn,rt,v,p,sum);
        sonnum[p] += sonnum[v];
        if(minn > max(sonnum[v],sum - sonnum[v])){
            minn = max(sonnum[v],sum - sonnum[v]);
            rt = i;
        }
    }
}

关于复杂度:

仅仅计算分治的复杂度

每个结点最多计算 l o g n logn logn 次,故复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

推荐题目:

POJ 1741 (点分治模版),题解:POJ 1741

HDU 4812(点分治, 技巧去同一子树贡献),题解:HDU 4812

HDU 4670(点分治 + 状压),题解:HDU 4670

SPOJ QTREE4 Query on a tree IV (边分治 + 用堆维护分治结构) ,题解:SPOJ QTREE4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值