图论 LCA在线算法 倍增法

Lowest Common Ancestor:

如求A,B两点的LCA,先计算出各个结点的深度depth[],然后,通过递推公式求出各个结点的2次方倍的祖先ancestor[],假设depth[A] > depth[B],则找到depth[ancestor[A][i]] == depth[B]也就是A的某一祖先与B深度相同,然后,u = ancestor[A][i],通过ancestor[u][i] 与ancestor[B][i]比较找出LCA。

(ancestor[a][b] 表示与a的距离为2^b的祖先,则ancestor[a][0]表示为a的父亲。如 a->b->c->d->e,a为根, 则ancestor[e][2] 为a)

递推公式:ancestor[a][b] = ancestor[ancestor[a][b - 1]][b - 1]

Template:

#define NODE_SIZE 10010
#define ANC_SIZE 15
// ANC_SIZE = Log(2, NODE_SIZE)
int ancestors[NODE_SIZE][ANC_SIZE];
int depth[NODE_SIZE];

vector<int> childs[NODE_SIZE];

int LCAncestor(int u, int v) {
    if (depth[u] < depth[v]) { swap(u, v); }
    for (int i = ANC_SIZE ; i >= 0 ; --i) {
        if (depth[ancestors[u][i]] >= depth[v] ) {
            u = ancestors[u][i];
            if (depth[u] == depth[v]) { break; }
        }
    }
    if (u == v) { return u; }

    for (int i = ANC_SIZE - 1; i >= 0 ; --i) {
        if (ancestors[u][i] != ancestors[v][i]) {
            u = ancestors[u][i]; 
            v = ancestors[v][i];
        }
    }

    return ancestors[u][0];
}
void GetDepth(int rt, int dep) {
    depth[rt] = dep;
    for (int i = 0 ; i < childs[rt].size(); ++i) {
        GetDepth(childs[rt][i], dep + 1);
    }
}


GetDepth(root, 1);
for (int i = 1; i < ANC_SIZE ; ++i) {
    for (int j = 1 ; j <= n ; ++j) {
        ancestors[j][i] = ancestors[ancestors[j][i - 1]][i - 1];
    }
}
printf("%d\n", LCAncestor(u, v));


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值