zoukankan      html  css  js  c++  java
  • 图论-LCA的3种求法:离线Tarjan、树上倍增、 欧拉序+RMQ

    1. 树上倍增

    f[i][k] 表示节点 i 向上第 2个节点。mx 是树的最大深度。

    预处理:

    先 DFS 得到 f[i][0] ,然后:

    1 for (k = 1; k <= mx; ++k)
    2     for (i = 1; i <= N; ++i)
    3         dad[i][k] = dad[dad[i][k-1]][k-1];

    求 LCA :

     1 int LCA(int t1, int t2)
     2 {
     3     
     4     int i;
     5     ans = 0;
     6     if (depth[t1] < depth[t2]) swap(t1, t2);
     7     int tmp = depth[t1] - depth[t2];
     8     for (i = 0; i <= mx; ++i)
     9         if ((tmp>>i) & 1)
    10             ans += 1<<i, t1 = dad[t1][i];
    11     if (t1 == t2) return t1;
    12     for (i = mx; i >= 0; --i)
    13         if (dad[t1][i] != dad[t2][i])
    14             t1 = dad[t1][i], t2 = dad[t2][i];
    15     return dad[t1][0];
    16 }

    2. 欧拉序+RMQ

    DFS 得到树的欧拉序列,记录每个点在欧拉序列中第一次出现的位置 pos[i] 。

    x, y 的 LCA 即为欧拉序列的 [pos[x], pos[y]] 区间的最小值。预处理欧拉序列,查询最小值的操作用 RMQ 实现。这样查询的复杂度是 O(1) 的,比法 1 树上倍增的 O(log N) 优秀。

    3. 离线 Tarjan

  • 相关阅读:
    29. Divide Two Integers
    leetCode 17. Letter Combinations of a Phone Number
    查找
    快速排序
    希尔排序
    插入排序
    归并排序,还有非递归方式没写
    堆排序--还有递归法没有写
    c++实现字符串全排序
    归并排序
  • 原文地址:https://www.cnblogs.com/ghcred/p/9301587.html
Copyright © 2011-2022 走看看