使用Binary Lifting实现LCA

本文介绍了如何利用层次关系和深度优先搜索构建LCA类,用于解决给定图中两个节点的最近公共祖先问题。通过edges列表初始化树结构,并演示了如何查询任意两个节点的最近公共祖先。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

共有n个节点,n-1条边存储在edges中
 

import math

class LCA:
    def __init__(self, edges):
        n = len(edges)+1
        self.log = math.ceil(math.log2(n))
        self.parent = [[-1 for _ in range(self.log)] for _ in range(n)]
        self.depth = [0] * n
        self.graph = [[] for _ in range(n)]
        for u, v in edges:
            self.graph[u].append(v)
            self.graph[v].append(u)
        self.dfs(0, -1)

    def dfs(self, node, par):
        for child in self.graph[node]:
            if child != par:
                self.depth[child] = self.depth[node] + 1
                self.parent[child][0] = node
                for i in range(1, self.log):
                    if self.parent[child][i - 1] != -1:
                        self.parent[child][i] = self.parent[self.parent[child][i - 1]][i - 1]
                self.dfs(child, node)

    def query(self, u, v):
        if self.depth[u] < self.depth[v]:
            u, v = v, u
        diff = self.depth[u] - self.depth[v]
        for i in range(self.log):
            if diff & (1 << i):
                u = self.parent[u][i]

        if u == v:
            return u

        for i in reversed(range(self.log)):
            if self.parent[u][i] != self.parent[v][i]:
                u = self.parent[u][i]
                v = self.parent[v][i]

        return self.parent[u][0]

# 现在重新执行测试代码
edges = [[0, 1], [1, 2], [1, 3], [3, 4]]
lca = LCA(edges)

test_pairs = [(2, 4), (3, 4), (2, 3)]
results = []
for u, v in test_pairs:
    ancestor = lca.query(u, v)
    results.append((u, v, ancestor))

print(results)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值