倍增法求LCA
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 #include<map> 7 #include<queue> 8 using namespace std; 9 #define INF 0x3f3f3f3f 10 #define M(a, b) memset(a, b, sizeof(a)) 11 const int N = 1e4 + 10, M = 20; 12 int deep[N], p[N][25]; 13 vector<int> G[N]; 14 15 void dfs(int u, int fa) { 16 for (int i = 1; i <= M; ++i) 17 p[u][i] = p[p[u][i-1]][i-1]; 18 for (int i = 0; i < G[u].size(); ++i) { 19 int v = G[u][i]; 20 if (v == fa || deep[v]) continue; 21 deep[v] = deep[u] + 1; 22 p[v][0] = u; 23 dfs(v, u); 24 } 25 } 26 27 int lca(int a, int b) { 28 if (deep[a] < deep[b]) swap(a, b); 29 for (int det = deep[a]-deep[b], i = 0; det; det >>= 1, ++i) 30 if (det & 1) a = p[a][i]; 31 if (a == b) return a; 32 for (int i = M-1; i >= 0; --i) { 33 if (p[a][i] == p[b][i]) continue; 34 a = p[a][i]; 35 b = p[b][i]; 36 } 37 return p[a][0]; 38 }