码迷,mamicode.com
首页 > 其他好文 > 详细

LCA最近公共祖先

时间:2019-04-08 13:06:24      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:using   lca   \n   back   pre   for   ==   公共祖先   turn   

 不会 准备研究一波!!!

 1 #include<bits/stdc++.h>
 2 const int maxn = 500010;
 3 using namespace std;
 4 vector<int> g[maxn];
 5 int par[20][maxn], dep[maxn], n, m, ml;
 6 void dfs(int v, int p, int d)
 7 {
 8     par[0][v] = p;
 9     dep[v] = d;
10     for (int i = 0; i < g[v].size(); ++i){
11         if (g[v][i] != p) dfs(g[v][i], v, d + 1);
12     }
13     return ;
14 }
15 void init(int v)
16 {
17     dfs(v, -1, 0);
18     int sum = 1;
19     while (sum <= n) sum <<= 1, ++ml;
20     for (int k = 0; k < ml; ++k){
21         for (int v = 1; v <= n; ++v){
22             if (par[k][v] == -1) par[k + 1][v] = -1;
23             else par[k + 1][v] = par[k][par[k][v]];
24         }
25     }
26     return ;
27 }
28 int lca(int u, int v)
29 {
30     if (dep[u] > dep[v]) swap(u, v);
31     for (int k = 0; k < ml; ++k){
32         if (((dep[v] - dep[u]) >> k) & 1) v = par[k][v];
33     }
34     if (u == v) return u;
35     for (int k = ml; k >= 0; --k){
36         if (par[k][u] != par[k][v]) u = par[k][u], v = par[k][v];
37     }
38     return par[0][u];
39 }
40 int main()
41 {
42     int s, u, v;
43     scanf("%d %d %d", &n, &m, &s);
44     int t = n;
45     while (--t){
46         scanf("%d %d", &u, &v);
47         g[u].push_back(v);
48         g[v].push_back(u);
49     }
50     init(s);
51     while (m--){
52         scanf("%d %d", &u, &v);
53         printf("%d\n", lca(u, v));
54     }
55     return 0;
56 }

 

LCA最近公共祖先

标签:using   lca   \n   back   pre   for   ==   公共祖先   turn   

原文地址:https://www.cnblogs.com/zxz666/p/10669536.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!