Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
lca.hpp
[詳解]
1#include"../../../kyopro_library/template.hpp"
2
3/// @brief LCA
4/// @ref verify: https://onlinejudge.u-aizu.ac.jp/status/users/Today03/submissions/1/GRL_5_C/judge/10572843/C++17
5struct LCA {
6 LCA(const vector<vector<int>>& g, int root=0) {
7 int n=g.size(), k=1;
8 while((1<<k)<n) k++;
9 par=vector<vector<int>>(k,vector<int>(n,-1)),dep=vector<int>(n);
10 dfs(g,root,-1);
11 for(int i=0; i<k-1; i++) for(int j=0; j<n; j++) par[i+1][j]=(par[i][j]==-1?-1:par[i][par[i][j]]);
12 }
13
14 int lca(int u, int v) {
15 if(dep[u]<dep[v]) swap(u,v);
16 int k=par.size();
17 for(int i=0; i<k; i++) if((dep[u]-dep[v])>>i&1) u=par[i][u];
18 if(u==v) return u;
19 for(int i=k-1; i>=0; i--) if(par[i][u]!=par[i][v]) u=par[i][u], v=par[i][v];
20 return par[0][u];
21 }
22
23 int distance(int u, int v) { return dep[u]+dep[v]-2*dep[lca(u,v)]; }
24
25 bool is_on_path(int u, int v, int x) { return distance(u,x)+distance(x,v)==distance(u,v); }
26
27 int climb(int u, int d) {
28 int k=par.size();
29 for(int i=k-1; i>=0; i--) if(d>>i&1) u=par[i][u];
30 return u;
31 }
32
34 vector<int> dep;
35
36private:
37 void dfs(const vector<vector<int>>& g, int now, int pre) {
38 par[0][now]=pre; dep[now]=(pre==-1 ? 0 : dep[pre]+1);
39 for(int nxt: g[now]) if(nxt!=pre) dfs(g,nxt,now);
40 }
41};
LCA verify: https://onlinejudge.u-aizu.ac.jp/status/users/Today03/submissions/1/GRL_5_C/judge/1057284...
Definition lca.hpp:5
int lca(int u, int v)
Definition lca.hpp:14
int distance(int u, int v)
Definition lca.hpp:23
vector< vector< int > > par
Definition lca.hpp:33
vector< int > dep
Definition lca.hpp:34
int climb(int u, int d)
Definition lca.hpp:27
bool is_on_path(int u, int v, int x)
Definition lca.hpp:25
LCA(const vector< vector< int > > &g, int root=0)
Definition lca.hpp:6