树链剖分 模版

最裸的树剖模板,用子节点数来判断的不严格重链,顺便带个LCA


#include<iostream>
#include<vector>
using namespace std;
vector<int> lin[500005];
int in[500005],size[500005],fa[500005],top[500005],ans,n,num;
int abs(int x)
{
    return x>=0?x:-x;
}
void dfs1(int x,int pre)
{
    in[x]=++num;
    fa[x]=pre;
    for (int i=0;i<lin[x].size();i++)
    {
        int nex=lin[x][i];
        if (nex==pre)   continue;
        dfs1(nex,x);
    }
    size[x]=num-in[x]+1;
}
void dfs2(int x,int t)
{
    in[x]=++num;
    top[x]=t;
    if (size[x]==1) return;
    int msize=0,heavy=0;//一定要赋初始值!
    for (int i=0;i<lin[x].size();i++)
    {
        int nex=lin[x][i];
        if (nex==fa[x]) continue;
        if (size[nex]>msize)
        {
            msize=size[nex];
            heavy=nex;
        }
    }
    dfs2(heavy,t);
    for (int i=0;i<lin[x].size();i++)
    {
        int nex=lin[x][i];
        if (nex==fa[x] || nex==heavy) continue;
        dfs2(nex,nex);
    }
}
void lca(int x,int y)
{
    int dis=0;
    while (top[x]!=top[y])
    {
        if (deep[top[x]]!=deep[top[y]])
        {
            dis+=in[x]-in[top[x]];
            x=fa[top[x]];
        }
        else
        {
            dis+=in[y]-in[top[y]];
            y=fa[top[y]];
        }
    }
    dis+=abs(in[x]-in[y])+1;
    return dis;
}
int main()
{
    cin>>n;
    for (int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        lin[a].push_back(b);
        lin[b].push_back(a);
    }
    num=0;  dfs1(1,0);
    num=0;  dfs2(1,1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值