题目
题解
求三个结点到一个结点距离之和最小的结点以及距离和
求出两两lca,其中有两个相同,答案则为另一个
code
#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define ull long long
const int maxn = 5e5 + 7;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
return s * w;
}
int T, n, m, num_edge = 0;
struct Edge { int next, to, dis; } edge[maxn << 1];
int head[maxn], fa[maxn][20], depth[maxn], dis[maxn];
inline void add(int from, int to, int dis) {
edge[++num_edge].to = to;
edge[num_edge].dis = dis;
edge[num_edge].next = head[from];
head[from] = num_edge;
}
void bfs(int rt) {
queue<int> q;
while (!q.empty()) q.pop();
fa[rt][0] = rt; depth[rt] = 0; dis[rt] = 0;
q.push(rt);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = 1; i < 20; ++i) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for (int i = head[u]; i; i = edge[i].next) {
int v = edge[i].to;
if (v == fa[u][0]) continue;
depth[v] = depth[u] + 1;
dis[v] = dis[u] + edge[i].dis;
fa[v][0] = u;
q.push(v);
}
}
}
int lca(int x, int y) {
if (depth[x] < depth[y]) swap(x, y);
for (int i = 0; i < 20; ++i) {
if ((depth[x] - depth[y]) & (1 << i)) x = fa[x][i];
}
if (x == y) return x;
for (int i = 19; i >= 0; i--) {
if (fa[x][i] != fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
inline int dist (int x, int y) { return dis[x] + dis[y] - 2 * dis[lca(x, y)]; }
int main() {
int n, m;
n = read(), m = read();
for (int i = 1; i < n; ++i) {
int a, b;
a = read(); b = read();
add(a, b, 1);
add(b, a, 1);
}
bfs(1);
for (int i = 1; i <= m; ++i) {
int a, b, c, point;
a = read(), b = read(), c = read();
int x = lca(a, b);
int y = lca(b, c);
int z = lca(a, c);
if (x == y) point = z;
else if (x == z) point = y;
else point = x;
printf("%d %d\n", point, dist(a, point) + dist(b, point) + dist(c, point));
}
// system("PAUSE");
return 0;
}