lca相关

1.两个点的lca
寻找两个点的lca
记录根节点到u的深度为depth[u],到节点v的深度为depth[v]
先让他们的深度保持一致,然后再一起向上走,知道找到lca
*/
vector<int>G[max_n];
int root;
int parent[max_n];
int depth[max_n];

void dfs(int v,int p,int d)
{
    parent[v]=p;
    depth[v]=d;
    for(int i=0;i<G[v].size();i++)
    {
        if(G[v][i]!=p)dfs(G[v][i],v,d+1);
    }
}
void init()
{
    dfs(root,-1,0)
}
int lca(int u,int v)
{
    while(depth[v]>depth[u]) v=parent[v];
    while(depth[u]>depth[v]) u=parent[u];
    
    while(u!=v)
    {
        u=parent[u];
        v=parent[v];
    }
    return u;
}

2.预处理数组解决多对节点lca问题

/*
parent[k][v]表示v点向根节点走2^k步所到达的点
根据parent数组可以高效地处理多对节点的lca
*/
vector<int>G[max_n];
int parent[200][max_n];
int depth[max_n];
void dfs(int v,int p,int d)
{
    parent[0][v]=p;
    depth[v]=d;
    for(int i=0;i<G[v].size();i++)
    {
        if(G[v][i]!=v)dfs(G[v][i],v,d+1);
    }
}

void init(int v)
{
    dfs(root,-1,0);
    for(int k=1;k+1<max_n;k++)
    {
        for(int v=0;v<V;v++)
        {
            if(parent[k][v]<0) parent[k+1][v]=-1;
            else parent[k+1][v]=parent[k][parent[k][v]];
        }
    }
}

int lca(int u,int v)
{
    if(depth[u]>depth[v])swap(u,v);
    for(int k=0;k<max_n;k++)
    {
        if(((depth[v]-depth[u])>>k)&1)
        {
            u=parent[u];
            v=parent[v];
        }
    }
    
    for(int k=max_n;k>=0;k--)
    {
        if(parent[k][u]!=parent[k][v])
        {
            u=parent[k][u];
            v=parent[k][v];
        }
    }
    return parent[0][u];
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值