Centroids 题解

类比 computer,记录 dp1 最大,次大和最大时儿子节点。

同时定义 sid[i]:=最大节点的子树根节点下标。

DFS1——

考虑一棵树,根为x,遍历到儿子y,根为i的子树节点数为sze[i]。

  1. 若sze[y]<=n/2,直接取值都可以,不用管他,故此时 dp1 更新一下 sze[y] 即可。
  2. 若反之,取极限 dp1[y].最大值更新即可。
void DFS1(int x=1,int par=-1){
    sze[x]=1;
    for(auto i:G[x]){
        int y=i;
        if(y==par)continue;
        DFS1(y,x);
        sze[x]+=sze[y];
        if(sze[y]>sze[sid[x]])sid[x]=y;
        int ins=(sze[y]<=n/2?sze[y]:dp1[y].maxn);
        if(dp1[x].maxn<ins){
            dp1[x].maxx=dp1[x].maxn;
            dp1[x].maxn=ins;
            dp1[x].pos=y;
        }
        else if(dp1[x].maxx<ins)dp1[x].maxx=ins;
    }
    return;
}

DFS2——

dp2[x]:=当这个点不为Centriod时,可以平摊节点的最大化数量
解释一下吧:


    if(sze[sid[x]]>n/2)out[x]=(sze[sid[x]]-dp1[x].maxn<=n/2);//如果均摊后能成功
    else if(n-sze[x]>n/2)out[x]=(n-sze[x]-dp2[x]<=n/2);//同上,只不过变成了父亲部
    for(auto i:G[x]){
        int y=i;
        if(y==par)continue;
        dp2[y]=max(dp2[y],(n-sze[x]>n/2?dp2[x]:n-sze[x]));
        if(dp1[x].pos==y)dp2[y]=max(dp2[y],dp1[x].maxx);
        else dp2[y]=max(dp2[y],dp1[x].maxn);
        DFS2(y,x);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值