HZNU-ACM寒假集训Day9小结
作者:互联网
LCA
Luogu P3379 https://www.luogu.com.cn/problem/P3379
#include<iostream> #include<cstdio> #include<string> #include<algorithm> #include<queue> #include<set> #include<map> const double PI = acos(-1.0); typedef long long ll; using namespace std; struct Edge { int t, next; }e[500010<<1]; //开两倍 int head[500010], tot; void add_edge(int x, int y) { e[++tot].t = y; e[tot].next = head[x]; head[x] = tot; } int depth[500010], fa[500001][22], lg[500001]; void dfs(int now, int fath) { //now表示当前节点,fath表示其父亲节点 fa[now][0] = fath; depth[now] = depth[fath] + 1; for (int i = 1; i <= lg[depth[now]]; i++) { fa[now][i] = fa[fa[now][i - 1]][i - 1]; //算法核心 } for (int i = head[now]; i; i = e[i].next) { if (e[i].t != fath) dfs(e[i].t, now); } } int LCA(int x, int y) { if (depth[x] < depth[y]) swap(x, y); while (depth[x] > depth[y]) x = fa[x][lg[depth[x] - depth[y]] - 1]; //先跳到同一层 if (x == y) return x; //如果x==y那LCA一定就是x for (int k = lg[depth[x]] - 1; k >= 0; k--) { //不断向上跳 if (fa[x][k] != fa[y][k]) { //因为要跳到LCA的下一层所以他们肯定不相等,不相等就跳过去 x = fa[x][k]; y = fa[y][k]; } } return fa[x][0]; } int main() { int n, m, s; scanf("%d%d%d", &n, &m, &s); for (int i = 1; i <= n - 1; i++) { int x, y; scanf("%d%d", &x, &y); add_edge(x, y); add_edge(y, x); } for (int i = 1; i <= n; i++) { //预先算出log2(i)+1的值,用的时候可以直接调用 lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); } dfs(s, 0); for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); printf("%d\n", LCA(x, y)); } return 0; }
标签:Day9,int,HZNU,d%,ACM,fa,depth,LCA,include 来源: https://www.cnblogs.com/hznumqf/p/12267910.html