LCA(最近公共祖先)——LCA倍增法

一、前人种树

博客:最近公共祖先 LCA 倍增法

博客:浅谈倍增法求LCA

 

二、沙场练兵

题目:POJ 1330 Nearest Common Ancestors

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const int MAXN = 10010;
const int DEG = 20;
  
struct Edge
{
  int to,next;
}edge[MAXN*2];
int head[MAXN],tot;
void addedge(int u,int v)
{
  edge[tot].to = v;
  edge[tot].next = head[u];
  head[u] = tot++;
}
void init()
{
  tot = 0;
  memset(head,-1,sizeof(head));
}
int fa[MAXN][DEG];//fa[i][j]表示结点i的第2^j个祖先
int deg[MAXN];//深度数组
  
void BFS(int root)
{
  queue<int>que;
  deg[root] = 0;
  fa[root][0] = root;
  que.push(root);
  while(!que.empty())
  {
    int tmp = que.front();
    que.pop();
    for(int i = 1;i < DEG;i++)
      fa[tmp][i] = fa[fa[tmp][i-1]][i-1];
    for(int i = head[tmp]; i != -1;i = edge[i].next)
    {
      int v = edge[i].to;
      if(v == fa[tmp][0])continue;
      deg[v] = deg[tmp] + 1;
      fa[v][0] = tmp;
      que.push(v);
    }
  
  }
}
int LCA(int u,int v)
{
  if(deg[u] > deg[v])swap(u,v);
  int hu = deg[u], hv = deg[v];
  int tu = u, tv = v;
  for(int det = hv-hu, i = 0; det ;det>>=1, i++)
    if(det&1)
      tv = fa[tv][i];
  if(tu == tv)return tu;
  for(int i = DEG-1; i >= 0; i--)
  {
    if(fa[tu][i] == fa[tv][i])
      continue;
    tu = fa[tu][i];
    tv = fa[tv][i];
  }
  return fa[tu][0];
}
bool flag[MAXN];
int main()
{
    int T;
  int n;
  int u,v;
  scanf("%d",&T);
  while(T--)
  {
    scanf("%d",&n);
    init();
    memset(flag,false,sizeof(flag));
    for(int i = 1;i < n;i++)
    {
      scanf("%d%d",&u,&v);
      addedge(u,v);
      addedge(v,u);
      flag[v] = true;
    }
    int root;
    for(int i = 1;i <= n;i++)
      if(!flag[i])
      {
        root = i;
        break;
      }
    BFS(root);
    scanf("%d%d",&u,&v);
    printf("%d\n",LCA(u,v));
  }
    return 0;
}
posted @   GGBeng  阅读(422)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示