LCA最近公共祖先

冷暖自知 提交于 2020-03-27 02:29:06

 不会 准备研究一波!!!

 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 }

题目   https://www.luogu.org/problemnew/show/P3379

自己写的一个倍增LCA

 1 #include<iostream>
 2 #include<cstring>
 3 //#include<bits/stdc++.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<stack>
 8 #include<cstdio>
 9 #include<map>
10 #include<set>
11 #define  si(a)       scanf("%d",&a)
12 #define  sl(a)       scanf("%lld",&a)
13 #define  sii(a,b)    scanf("%d%d",&a,&b)
14 #define  sll(a,b)    scanf("%lld%lld",&a,&b)
15 #define  queues      priority_queue
16 #define mod 998244353
17 #define mem(a)  memset(a,0,sizeof(a));
18 #define def(a) ((a)&(-a))
19 #define fi  first
20 #define se  second
21 #define mp  make_pair
22 #define  pb push_back
23 typedef long long ll;
24 //priority_queue<int,vector<int >,greater<int > >q;
25 const ll INF=0x3f3f3f3f;
26 //const double E=exp(1);
27 //const double PI=acos(-1);
28 using namespace std;
29 int de[500003];
30 int lg[500003];
31 int f[500003][30];
32 vector<int>ss[500003];
33 void get_lg()
34 {lg[0]=-1;
35     for(int i=1;i<=500000;i++)
36         lg[i]=lg[i>>1]+1;
37 }
38 void dfs(int p,int fa)
39 {  de[p]=de[fa]+1;
40     f[p][0]=fa;
41     for(int i=1;i<=lg[de[p]]+1;i++)
42         f[p][i]=f[f[p][i-1]][i-1];
43     for(int i=0;i<ss[p].size();i++)
44     { int x=ss[p][i];
45         if(x!=fa)
46         {
47             dfs(x,p);
48         }
49     }
50 }
51 int LCA(int a,int b)
52  {   if(de[a]<de[b])swap(a,b);
53     while(de[a]!=de[b])
54     {
55         a=f[a][lg[de[a]-de[b]]];
56     }
57    if(a==b)return a;
58        for(int i=lg[de[a]];i>=0;i--)
59        {
60            if(f[a][i]!=f[b][i])
61             a=f[a][i],b=f[b][i];
62        }
63    return f[a][0];
64  }
65  int main()
66 {  ios::sync_with_stdio(false);
67     int n,m,s;
68     scanf("%d%d%d",&n,&m,&s);
69     for(int i=1;i<n;i++)
70     {
71         int a,b;
72         scanf("%d%d",&a,&b);
73         ss[a].pb(b);
74         ss[b].pb(a);
75     }
76     get_lg();
77     dfs(s,0);
78     for(int i=1;i<=n;i++)
79     {
80         int a,b;
81         scanf("%d%d",&a,&b);
82         printf("%d\n",LCA(a,b));
83     //    cout<<LCA(a,b)<<endl;
84     }
85 }
View Code

 又有一个树链剖分求LCA

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 const int maxn=500000+5;
 4 const int INF=0x3f3f3f3f;
 5 using namespace std;
 6 const ll MAX=100000
 7 int read(){int x=0,f=1;char s=getchar();for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1;for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0';return x*f;}
 8 vector<int>q[maxn];
 9 int f[maxn];
10 int d[maxn];
11 int siz[maxn];
12 int son[maxn];
13 
14 int top[maxn];
15 int id[maxn];
16 int rk[maxn];
17 int dfs(int a,int fa)
18 {
19     f[a]=fa;
20     d[a]=d[fa]+1;
21     siz[a]=1;
22     for(int i=0; i<q[a].size(); i++)
23     {
24         int z=q[a][i];
25         if(z!=fa)
26         {
27             dfs(z,a);
28             siz[a]+=siz[z];
29             if(!son[a]||siz[z]>siz[son[a]])
30                 son[a]=z;
31         }
32     }
33     return 0;
34 }
35 int sum;
36 void dfs1(int a,int b)
37 {
38     top[a]=b;
39     if(!son[a])
40         return ;
41     dfs1(son[a],b);
42     for(int i=0; i<q[a].size(); i++)
43     {
44         int z=q[a][i];
45         if(z!=f[a]&&z!=son[a])
46             dfs1(z,z);
47     }
48 }
49 int lca(int a,int b)
50 {
51     while(top[a]!=top[b])
52     {
53         d[top[a]]>d[top[b]]?a=f[top[a]]:b=f[top[b]];
54 
55     }
56     return d[a]<d[b]?a:b;
57 }
58 int main()
59 {
60     ios::sync_with_stdio(false);
61     int n,m,s;
62     n=read();m=read();s=read();
63     for(int i=1; i<n; i++)
64     {
65         int a,b;
66         a=read();
67         b=read();
68         q[a].pb(b);
69         q[b].pb(a);
70     }
71     dfs(s,0);
72     dfs1(s,s);
73     while(m--)
74     {
75         int a,b;
76         a=read();
77         b=read();
78         cout<<lca(a,b)<<endl;
79     }
80 }
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!