classEdge { public: int toVertex, fromVertex; int next; int LCA; Edge() : toVertex(-1), fromVertex(-1), next(-1), LCA(-1) {}; Edge(int u, int v, int n) : fromVertex(u), toVertex(v), next(n), LCA(-1) {}; };
constint MAX = 100; int head[MAX], queryHead[MAX]; Edge edge[MAX], queryEdge[MAX]; int parent[MAX], visited[MAX]; int vertexCount, edgeCount, queryCount;
voidinit() { for (int i = 0; i <= vertexCount; i++) { parent[i] = i; } }
for (int i = head[u]; i != -1; i = edge[i].next) { Edge& e = edge[i]; if (!visited[e.toVertex]) { tarjan(e.toVertex); parent[e.toVertex] = u; } }
for (int i = queryHead[u]; i != -1; i = queryEdge[i].next) { Edge& e = queryEdge[i]; if (visited[e.toVertex]) { queryEdge[i ^ 1].LCA = e.LCA = find(e.toVertex); } } }
int n, m, s; structlca { int cnt, head[maxn]; structedge { int to, next; } e[maxn << 1]; voidadd(int u, int v){ e[++cnt] = { v, head[u] }; head[u] = cnt; e[++cnt] = { u, head[v] }; head[v] = cnt; }
int dep[maxn]; int lg[maxn]; int fa[maxn][22];
voidinit(){ for (int i = 1; i <= n; ++i) { lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); // cout << i << " -> " << lg[i] << endl; } }
voiddfs(int now, int pre){ fa[now][0] = pre; dep[now] = dep[pre] + 1; for (int i = 1; i <= lg[dep[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].to != pre) dfs(e[i].to, now); }
intLCA(int x, int y){ if (dep[x] < dep[y]) swap(x, y); while (dep[x] > dep[y]) x = fa[x][lg[dep[x] - dep[y]] - 1]; if (x == y) return x; for (int k = lg[dep[x]] - 1; k >= 0; --k) if (fa[x][k] != fa[y][k]) x = fa[x][k], y = fa[y][k]; return fa[x][0]; }
} Lca; intmain(){ scanf("%d%d%d", &n, &m, &s); for (int i = 1; i < n; ++i) { int x, y; scanf("%d%d", &x, &y); Lca.add(x, y); } Lca.init(); Lca.dfs(s, 0); for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); printf("%d\n", Lca.LCA(x, y)); } return0; }
int n, m, r; int ans[maxn]; structLCA { int vis[maxn];
int s[maxn]; voidinit(){ for (int i = 1; i <= n; ++i) s[i] = i; } intfind(int x){ return s[x] == x ? x : s[x] = find(s[x]); }
int tot, first[maxn]; structquery { int to, next; } q[maxn << 1]; voidinsert(int x, int y){ q[++tot] = { y, first[x] }; first[x] = tot; q[++tot] = { x, first[y] }; first[y] = tot; }
int cnt, head[maxn]; structedge { int to, next; } e[maxn << 1]; voidadd(int u, int v){ e[++cnt] = { v, head[u] }; head[u] = cnt; e[++cnt] = { u, head[v] }; head[v] = cnt; }
voidTarjan(int u, int fa){ for (int i = head[u]; i; i = e[i].next) { if (e[i].to == fa) continue; Tarjan(e[i].to, u); s[e[i].to] = u; } for (int i = first[u]; i; i = q[i].next) { if (!vis[q[i].to]) continue; ans[(i + 1) / 2] = find(q[i].to); } vis[u] = 1; } } Lca;
intmain(){ scanf("%d%d%d", &n, &m, &r); Lca.init(); for (int i = 1; i < n; ++i) { int x, y; scanf("%d%d", &x, &y); Lca.add(x, y); } for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); Lca.insert(x, y); } Lca.Tarjan(r, -1); for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]); return0; }
About this Post
This post is written by OwlllOvO, licensed under CC BY-NC 4.0.