P4281 [AHOI2008]緊急集合 聚會 題解
阿新 • • 發佈:2022-05-29
就是求三個點到同一個點的最短路徑。
Solution
我們知道在一顆樹上,三個點的 \(LCA\) 只有兩個點。
那最後肯定是移動到其中一個點上。
那移動到哪個點上更優呢。
我們都求出來然後取個 \(\min\) 不就行了嘛 /qd
於是這個藍題就變成了 \(LCA\) 板子。
/* Work by: TLE_Automation */ #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define LL long long //#define int long long using namespace std; const int N = 1e6 + 10; const int MAXN = 2e5 + 10; inline char readchar() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } inline int read() { #define readchar getchar int res = 0, f = 0;char ch = readchar(); for(; !isdigit(ch); ch = readchar()) if(ch == '-') f = 1; for(; isdigit(ch); ch = readchar()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res; } inline void print(int x) { if (x < 0 ) putchar('-'), x = -x; if (x > 9 ) print(x / 10); putchar(x % 10 + '0'); } int n, Q, head[N], dep[N], f[N][30], num_adge = 0; struct Node {int u, v, nxt;} e[N]; void add(int u, int v) {e[++num_adge] = (Node) {u, v, head[u]}, head[u] = num_adge;} void dfs(int u, int fa) { dep[u] = dep[fa] + 1, f[u][0] = fa; for(int i = 1; i <= 20; i++) f[u][i] = f[f[u][i - 1]][i - 1]; for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if(v ^ fa) dfs(v, u); } } int LCA(int x, int y) { if(dep[x] < dep[y]) swap(x, y); for(int i = 20; i >= 0; i--) { if(dep[f[x][i]] >= dep[y]) x = f[x][i]; if(x == y) return x; } for(int i = 20; i >= 0; i--) { if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int ans1 = 0, ans2 = 0; int lca1, lca2; int Ans; signed main() { n = read(), Q = read(); for(int i = 1, u, v; i <= n - 1; i++) u = read(), v = read(), add(u, v), add(v, u); dfs(1, 0); for(int i = 1; i <= Q; i++) { int a = read(), b = read(), c = read(); int t1 = LCA(a, b), t2 = LCA(b, c), t3 = LCA(a, c); // printf("\n%d %d %d\n\n", t1, t2, t3); if(t1 == t2) { lca1 = t1, lca2 = t3; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } else if(t1 == t3) { lca1 = t1, lca2 = t2; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } else if(t2 == t3) { lca1 = t2, lca2 = t1; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } if(ans1 < ans2) Ans = lca1; else Ans = lca2; printf("%d %d\n", Ans, min(ans1, ans2)); } }